2013-08-27 2 views
2

У меня есть два объекта (A & B). A имеет отношение один к большому отношению с объектом B. Первичный ключ объекта A является автоматическим приращением, где в качестве первичного ключа объекта B является составным (состоящим из PK объекта A в качестве внешнего ключа и одного автоматически увеличиваемого id).javax.persistence.EntityExistsException: другой объект с тем же значением идентификатора уже был связан с сеансом

Примечание: Я использую EJB 3.1 с MySQL, Jboss7

Я заселить сущности А из моих бизнес-объектов и создать его следующим образом.

A a = new A(); 
Set<B> bEntitiesList = new HashSet<B>(); 
B b = new B(); 
b.setCompositeKey(new compositeKey()); // I am not setting any value in the 
// key and it will have null values for idA and idB. 
// idB is null because it will be auto incremented in this table by MySQL 
bEntitiesList.put(b); 
a.setBEntities(bEntitiesList); 
entityManager.persist(a); 

Всякий раз, когда я прохожу один объект из Entity B в списке bEntities то программа работает, как ожидается, все поля в базе данных населены правильно, но когда я добавить более одного объекта сущности B в списке bEntities я получить исключение "javax.persistence.EntityExistsException: другой объект с тем же значением идентификатора уже был связан с сеансом". Я не уверен, как обойти это. В сообщении четко сказано, что сеанс hibernate обнаружил повторяющиеся записи (что связано с тем, что составной ключ имеет переопределенные методы, созданные по умолчанию MyEclipse, который генерирует один и тот же хэш-код, но я не уверен, что это вызывает проблему). Пожалуйста, скажите мне, как я могу это решить. Нужно ли переопределять методы equals и hashcode в классе составных клавиш? Заранее спасибо.

public class A 
{ 
    private Integer idA; 
    private Set<B> bEntities = new HashSet<B>(0); 
    @Id 
    @GeneratedValue(strategy = IDENTITY) 
    @Column(name = "A", unique = true, nullable = false) 
    public Integer getIdA() { 
     return this.idA; 
    } 
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "A") 
    public Set<B> getBEntities() { 
     return this.bEntities; 
    } 
} 

public class B 
{ 
    private compositeKey key; 
    private A entityA; 
    @EmbeddedId 
    @AttributeOverrides({ 
    @AttributeOverride(name="idB",[email protected](name="idB",nullable=false))}) 
    public compositeKey getKey() { 
     return this.key; 
    } 
    public void setKey(compositeKey key) { 
     this.key = key; 
    } 
    @ManyToOne(fetch = FetchType.LAZY) 
    @MapsId("providerReferenceNo") 
    @JoinColumn(name = "idA", nullable = false, insertable = false, updatable = false) 
    public A getEntityA() { 
     return this.entityA; 
    } 
} 


@Embeddable 
public class compositeKey { 
private Integer idA; 
private Integer idB; 

@GeneratedValue(strategy = IDENTITY) 
@Column(name = "idB", nullable = false) 
public Integer getIdB() { 
    return this.idB; 
} 
@Column(name = "idA", nullable = false) 
public Integer getIdA() { 
    return this.idA; 
} 
+0

http://stackoverflow.com/questions/1074081/hibernate-error-org-hibernate-nonuniqueobjectexception-a-different-object-with? –

+0

Спасибо, Майкл. Я уже видел этот пост. Я отлаживал приложение, и я обнаружил, что всякий раз, когда я создаю один объект составного класса, он получает хэш-код, позволяющий говорить ab871c, и он корректно сохраняется в базе данных, но когда я создаю несколько объектов; все объекты получают одинаковый хэш-код, то есть ab871c. Почему я получаю такое поведение? Это связано с тем, что оба поля в составномKey равны нулю? Есть ли обходной путь для этого? –

ответ

1

Я думаю, ваша проблема может иметь что-то делать с тем, как хэш-код/​​Равно не соответствует идентичности объектов в соответствии с JPA/EJB3.1.

Попробуйте добавить методы hashCode/Equals в B, а также измените это bEntities на список, или если вы сохраните его в наборе, убедитесь, что данные, которые hashCode/Equals используют до его добавления в набор, гидратируются. Вероятно, вы должны сделать это, добавив hashCode и равные методы в CompositeKey и разделив их на хэш-код B и равный.

Btw, вы должны добавить методы hashCode и Equals в CompositeKey. Одна из причин использования CompositeKey заключается в том, чтобы сообщить структуре персистентности, как сравнивать с составными ключами.

+0

методы hashCode и equals уже переопределены в классе compositeKey, но реализация является стандартной по умолчанию (которая была предоставлена ​​MyEclipse, когда я создал объекты и фасады). Что вы подразумеваете под «Вероятно, вы должны сделать это, добавив методы hashCode и equals в CompositeKey и дефферируя их в хэш-коде B и равным». Лично я считаю то же самое, что проблема в том, как hashCode/equals соответствуют идентификатору объекта в JPA/EJBs 3.1. Где я могу найти, как JPA/EJB3.1 идентифицирует повторяющиеся сущности в сеансе? Каковы критерии? –

+0

У B есть hashCode и Equals? –

+0

Нет, B не имеет hashCode & equals. –

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

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