2015-06-18 7 views
2

У меня проблема с Hibernate EntityManager.Hibernate EntityManager не бросает EntityExistsException при сохранении

Вот моя 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; 
} 

My Element это:

@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()[email protected]] 

Если я теперь вставить элемент с Индекс (Имя), который уже существует, я получаю эти сообщения назад:

To persist: Event [name=Mercury, maturity=monthEnd, delay=0, toString()[email protected]] 
PersistanceHolder: [email protected] 
EntityManager: [email protected] 
CRUDDao: [email protected] 
Thread: Thread[qtp1055127737-17,5,main] 

Таким образом, исключение EntityExistsException и все в порядке.
Но на втором прогоне я получаю это:

To persist: Event [name=Mercury, maturity=monthEnd, delay=0, toString()[email protected]] 
PersistanceHolder: [email protected] 
EntityManager: [email protected] 
CRUDDao: [email protected] 
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-утверждения?

Спасибо, Джош

+0

Что вы имеете в виду под "удалить заявления JDBC, которые остаются"? –

+0

Что происходит между двумя прогонами? откуда начинается исходный экземпляр? –

+0

>> INFO: HHH000010: при выпуске пакета все еще содержались утверждения JDBC << при следующем взаимодействии с БД возникает ошибка, потому что пакет не пуст – schnawel007

ответ

0

я получил ответ. Здесь для всех, кто получает ту же ошибку:

Просто добавьте операцию слияния перед продолжением операции.

PS: Я не знаю, почему этот вопрос получил голоса, потому что это законный вопрос. Javadoc persist говорит:

Make an instance managed and persistent.

Это не помогает! Он пытается создать его в базе данных. Поэтому его сначала пытаются сохранить его, а затем управлять им. Javadoc слияния говорит:

Merge the state of the given entity into the current persistence context.

Это звучит как перезапись, так что я думал, что вы не можете использовать его здесь.

1

Вы должны использовать функцию persist только для объектов в состоянии NEW/TRANSIENT. Поскольку вы подаете заявку на присвоенные идентификаторы, вам лучше использовать слияние вместо этого (поскольку Hibernate не может определить, является ли предоставленный объект NEW или DETACHED).

Таким образом, вместо:

entityManager.persist(element); 

использовать это:

entityManager.merge(element); 
Смежные вопросы