Hibernate EntityManager 不会在持久化时抛出 EntityExistsException
Hibernate EntityManager doesn't throw EntityExistsException on persist
我有 Hibernate EntityManager 的问题。
这是我的 DAO 函数:
public Boolean create(T element)
{
System.out.println("To persist: "+element);
System.out.println("PersistanceHolder: "+holder);
System.out.println("EntityManager: "+entityManager);
System.out.println("CRUDDao: "+this);
System.out.println("Thread: "+Thread.currentThread());
entityManager.getTransaction().begin();
try
{
entityManager.persist(element);
}
catch(EntityExistsException e)
{
entityManager.getTransaction().rollback();
return Boolean.FALSE;
}
entityManager.getTransaction().commit();
return Boolean.TRUE;
}
我的元素是这样的:
@Entity
public class Event {
@Id
String name;
Maturity maturity;
Integer delay;
public Event() {
}
public Event(String name, Maturity maturity, Integer delay) {
super();
this.name = name;
this.maturity = maturity;
this.delay = delay;
}
public String getName() {
return name;
}
public Maturity getMaturity() {
return maturity;
}
public Integer getDelay() {
return delay;
}
@Override
public String toString() {
return "Event [name=" + name + ", maturity=" + maturity + ", delay="
+ delay + ", toString()=" + super.toString() + "]";
}
}
数据库中的元素如下所示:
Added: Event [name=Mercury, maturity=monthEnd, delay=0, toString()=bc.bacon.egg.data.local.pojos.events.Event@3b43dc25]
如果我现在插入一个索引(名称)已经存在的元素,我会收到此消息:
To persist: Event [name=Mercury, maturity=monthEnd, delay=0, toString()=bc.bacon.egg.data.local.pojos.events.Event@7025bd08]
PersistanceHolder: bc.bacon.egg.data.local.PersistanceHolder@3d9d91bd
EntityManager: org.hibernate.jpa.internal.EntityManagerImpl@33cb2ee5
CRUDDao: bc.bacon.egg.data.local.dao.events.EventsDao@6073d6f3
Thread: Thread[qtp1055127737-17,5,main]
因此抛出 EntityExistsException,一切正常。
但是在第二个 运行 我得到这个:
To persist: Event [name=Mercury, maturity=monthEnd, delay=0, toString()=bc.bacon.egg.data.local.pojos.events.Event@700576a4]
PersistanceHolder: bc.bacon.egg.data.local.PersistanceHolder@3d9d91bd
EntityManager: org.hibernate.jpa.internal.EntityManagerImpl@33cb2ee5
CRUDDao: bc.bacon.egg.data.local.dao.events.EventsDao@6073d6f3
Thread: Thread[qtp1055127737-16,5,main]
Hibernate: insert into Event (delay, maturity, name) values (?, ?, ?)
Jun 18, 2015 3:10:34 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 23505, SQLState: 23505
Jun 18, 2015 3:10:34 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Eindeutiger Index oder Primärschlüssel verletzt: "PRIMARY_KEY_3 ON PUBLIC.EVENT(NAME) VALUES ('Mercury', 1)"
Unique index or primary key violation: "PRIMARY_KEY_3 ON PUBLIC.EVENT(NAME) VALUES ('Mercury', 1)"; SQL statement:
insert into Event (delay, maturity, name) values (?, ?, ?) [23505-187]
Jun 18, 2015 3:10:34 PM org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl release
INFO: HHH000010: On release of batch it still contained JDBC statements
Jun 18, 2015 3:10:34 PM com.vaadin.server.DefaultErrorHandler doDefault
现在我的问题是,为什么第一次调用正常并且发现了重复,但第二次 运行 却不行?
好吧,我可以捕获在 commit() 函数中抛出的异常,但是,我怎么能删除剩余的 JDBC 语句?
谢谢,
乔希
我得到了答案。在这里给所有遇到同样错误的人:
只需在持久化操作之前添加合并操作即可。
PS:我不知道为什么这个问题没有投票,因为它是一个合理的问题。 persist 的 Javadoc 说:
Make an instance managed and persistent.
它并没有使它得到管理!它试图在数据库中创建它。所以它首先试图坚持它,然后管理它。 merge 的 Javadoc 说:
Merge the state of the given entity into the current persistence
context.
听起来像是覆盖,所以我认为你不能在这里使用它。
您应该只为处于 NEW/TRANSIENT 状态的实体调用持久化。因为您正在起诉分配的标识符,所以最好改用合并(因为 Hibernate 无法确定提供的实体是新实体还是分离实体)。
所以代替:
entityManager.persist(element);
使用这个:
entityManager.merge(element);
我有 Hibernate EntityManager 的问题。
这是我的 DAO 函数:
public Boolean create(T element)
{
System.out.println("To persist: "+element);
System.out.println("PersistanceHolder: "+holder);
System.out.println("EntityManager: "+entityManager);
System.out.println("CRUDDao: "+this);
System.out.println("Thread: "+Thread.currentThread());
entityManager.getTransaction().begin();
try
{
entityManager.persist(element);
}
catch(EntityExistsException e)
{
entityManager.getTransaction().rollback();
return Boolean.FALSE;
}
entityManager.getTransaction().commit();
return Boolean.TRUE;
}
我的元素是这样的:
@Entity
public class Event {
@Id
String name;
Maturity maturity;
Integer delay;
public Event() {
}
public Event(String name, Maturity maturity, Integer delay) {
super();
this.name = name;
this.maturity = maturity;
this.delay = delay;
}
public String getName() {
return name;
}
public Maturity getMaturity() {
return maturity;
}
public Integer getDelay() {
return delay;
}
@Override
public String toString() {
return "Event [name=" + name + ", maturity=" + maturity + ", delay="
+ delay + ", toString()=" + super.toString() + "]";
}
}
数据库中的元素如下所示:
Added: Event [name=Mercury, maturity=monthEnd, delay=0, toString()=bc.bacon.egg.data.local.pojos.events.Event@3b43dc25]
如果我现在插入一个索引(名称)已经存在的元素,我会收到此消息:
To persist: Event [name=Mercury, maturity=monthEnd, delay=0, toString()=bc.bacon.egg.data.local.pojos.events.Event@7025bd08]
PersistanceHolder: bc.bacon.egg.data.local.PersistanceHolder@3d9d91bd
EntityManager: org.hibernate.jpa.internal.EntityManagerImpl@33cb2ee5
CRUDDao: bc.bacon.egg.data.local.dao.events.EventsDao@6073d6f3
Thread: Thread[qtp1055127737-17,5,main]
因此抛出 EntityExistsException,一切正常。
但是在第二个 运行 我得到这个:
To persist: Event [name=Mercury, maturity=monthEnd, delay=0, toString()=bc.bacon.egg.data.local.pojos.events.Event@700576a4]
PersistanceHolder: bc.bacon.egg.data.local.PersistanceHolder@3d9d91bd
EntityManager: org.hibernate.jpa.internal.EntityManagerImpl@33cb2ee5
CRUDDao: bc.bacon.egg.data.local.dao.events.EventsDao@6073d6f3
Thread: Thread[qtp1055127737-16,5,main]
Hibernate: insert into Event (delay, maturity, name) values (?, ?, ?)
Jun 18, 2015 3:10:34 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 23505, SQLState: 23505
Jun 18, 2015 3:10:34 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Eindeutiger Index oder Primärschlüssel verletzt: "PRIMARY_KEY_3 ON PUBLIC.EVENT(NAME) VALUES ('Mercury', 1)"
Unique index or primary key violation: "PRIMARY_KEY_3 ON PUBLIC.EVENT(NAME) VALUES ('Mercury', 1)"; SQL statement:
insert into Event (delay, maturity, name) values (?, ?, ?) [23505-187]
Jun 18, 2015 3:10:34 PM org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl release
INFO: HHH000010: On release of batch it still contained JDBC statements
Jun 18, 2015 3:10:34 PM com.vaadin.server.DefaultErrorHandler doDefault
现在我的问题是,为什么第一次调用正常并且发现了重复,但第二次 运行 却不行? 好吧,我可以捕获在 commit() 函数中抛出的异常,但是,我怎么能删除剩余的 JDBC 语句?
谢谢, 乔希
我得到了答案。在这里给所有遇到同样错误的人:
只需在持久化操作之前添加合并操作即可。
PS:我不知道为什么这个问题没有投票,因为它是一个合理的问题。 persist 的 Javadoc 说:
Make an instance managed and persistent.
它并没有使它得到管理!它试图在数据库中创建它。所以它首先试图坚持它,然后管理它。 merge 的 Javadoc 说:
Merge the state of the given entity into the current persistence context.
听起来像是覆盖,所以我认为你不能在这里使用它。
您应该只为处于 NEW/TRANSIENT 状态的实体调用持久化。因为您正在起诉分配的标识符,所以最好改用合并(因为 Hibernate 无法确定提供的实体是新实体还是分离实体)。
所以代替:
entityManager.persist(element);
使用这个:
entityManager.merge(element);