Я вижу странное поведение при использовании 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
У меня возникла проблема при использовании GenerationType
IDENTITY
с единственной иерархией наследования таблицы.
Вот мои две сущности:
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. Естественно, я отвечу на любые ответы на оба сайта.
Какую версию драйвера PostgreSQL JDBC вы используете? –
Это postgresql-8.4-701.jdbc4.jar. Это хороший момент - я попробую другую версию, чтобы понять, не имеет ли это значение. – Stephen
@Matt Solnit Просто попробовал postgresql-8.3-605.jdbc4, и он работает нормально! Огромное спасибо. Если вы хотите записать это как ответ, я назначу его вам. – Stephen