2009-08-26 3 views
2

Я вижу странное поведение при использовании PostgreSQL в среде Hibernate/JPA с единственной иерархией наследования таблицы.Идентификатор PostgreSQL в иерархии одиночной таблицы JPA

Во-первых, мое окружение:

  • PostgreSQL 8.3
  • Spring 2.5.6SEC01
  • Hibernate-EntityManager 3.4.0.GA (устанавливается от Glassfish инструмента обновления)
  • Hibernate-распределение 3.3.1 .GA (устанавливается из инструмента обновления Glassfish)
  • Glassfish V2
  • Mac OS X 10.5.x

У меня возникла проблема при использовании GenerationTypeIDENTITY с единственной иерархией наследования таблицы.

Вот мои две сущности:

Parent.java

@Entity 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name="generation", discriminatorType=DiscriminatorType.STRING) 
@DiscriminatorValue("Parent") 
public class Parent implements Serializable { 
    private static final long serialVersionUID = 1L; 

    private Long id; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 
} 

Child.java

@Entity 
@DiscriminatorValue("Child") 
public class Child extends Parent { 
    private String babyName; 

    /** 
    * @return the babyName 
    */ 
    public String getBabyName() { 
     return babyName; 
    } 

    /** 
    * @param babyName the babyName to set 
    */ 
    public void setBabyName(String babyName) { 
     this.babyName = babyName; 
    } 
} 

DDL

create table Parent (generation varchar(31) not null 
        ,id bigserial not null 
        ,babyName varchar(255) 
        ,primary key (id) 
        ); 

Если я пытаюсь вставить новый родительский я получаю сообщение об ошибке:

org.postgresql.util.PSQLException: Bad value for type long : Parent 

Я оказался протоколирование в TRACE и это выход:

 
TRACE TransactionSynchronizationManager - Bound value [[email protected]] for key [[email protected]] to thread [httpSSLWorkerThread-8080-0] 
Hibernate: insert into Parent (generation) values ('Parent') 
SQL Error: 0, SQLState: 22003 
Bad value for type long : Parent 
TRACE TransactionInterceptor - Completing transaction for [com.xxx.yyy.service.MoveService.saveHuman] after exception: javax.persistence.PersistenceException: org.hibernate.exception.DataException: could not insert: [com.xxx.yyy.temp.Parent] 
TRACE RuleBasedTransactionAttribute - Applying rules to determine whether transaction should rollback on javax.persistence.PersistenceException: org.hibernate.exception.DataException: could not insert: [com.xxx.yyy.temp.Parent] 

Если изменить значение дискриминатора быть чем-то, что анализирует как длинный, например 123 Вставка выполнена успешно. Однако Hibernate, похоже, считает, что это значение дискриминатора - это идентификатор. Таким образом, следующий код:

Parent p = new Parent(); 
service.saveHuman(p); 

add(new Label("p", "p id is" + p.getId())); 

Показывает идентификатор как 123, а не значение первичного ключа, который является 1.

Если изменить тип поколения к AUTO одной последовательности создаются и вставка, кажется, работает ОК. Если я изменю его на SEQUENCE и объявим последовательность с аннотацией на уровне класса, она будет работать. Однако, согласно документации, которую я прочитал, PostgreSQL поддерживает оба типа генерации.

Я также пробовал точно такой же код и отключил базу данных с MySQL 5.0.51b. Кажется, это работает нормально.

Так это ошибка в моем коде, диалекте, Hibernate или PostgreSQL JDBC-драйвере? Любые идеи, как я могу сузить проблему? Любой, кто может повторить эту проблему, поскольку я попытался выполнить поиск и еще не видел эту проблему.

Примечание: Я также задал вопрос на Hibernate Forums. Естественно, я отвечу на любые ответы на оба сайта.

+0

Какую версию драйвера PostgreSQL JDBC вы используете? –

+0

Это postgresql-8.4-701.jdbc4.jar. Это хороший момент - я попробую другую версию, чтобы понять, не имеет ли это значение. – Stephen

+0

@Matt Solnit Просто попробовал postgresql-8.3-605.jdbc4, и он работает нормально! Огромное спасибо. Если вы хотите записать это как ответ, я назначу его вам. – Stephen

ответ

1

Я просто «портирую» это решение из комментариев выше ... используйте версию 8.3 драйвера PostgreSQL JDBC :-).

Смежные вопросы