Hibernate 3 составной ключ, один с генерируемым значением

#java #hibernate #orm

#java #гибернация #orm

Вопрос:

У меня есть эти две таблицы в базе данных revisions и Pagu

в Pagu модели я должен составлять ключ:

  • идентификатор int (автоматически генерируется базой данных)
  • таблица revision_id (foreign_key для ревизий)

как реализовать это в Hibernate 3?

это то, что я придумал

 @Entity
@Table(name="pagu"
    ,schema="dbo"
    ,catalog="dbname"
)
@IdClass(PaguId.class)
public class Pagu  implements java.io.Serializable {

 private int id;
 private int revisiId;
 private Entitas entitas;
 private Revisi revisi;
 ...

 @Id
 @GeneratedValue
 @Column(name="id", unique=true, nullable=false)
 public int getId() {
     return this.id;
 }

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

 @Id
 @Column(name="revisi_id", unique=true, nullable=false)
 public int getRevisiId() {
     return this.revisiId;
 }

 public void setRevisiId(int id) {
     this.id = id;
 }
  

И это мой класс PaguId

 @Embeddable
public class PaguId  implements java.io.Serializable {


     private int id;
     private int revisiId;

    public PaguId() {
    }

    public PaguId(int id, int revisiId) {
       this.id = id;
       this.revisiId = revisiId;
    }

    @Column(name="id", nullable=false)
    public int getId() {
        return this.id;
    }

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

    @Column(name="revisi_id", nullable=false)
    public int getRevisiId() {
        return this.revisiId;
    }

    public void setRevisiId(int revisiId) {
        this.revisiId = revisiId;
    }


   public boolean equals(Object other) {
         if ( (this == other ) ) return true;
         if ( (other == null ) ) return false;
         if ( !(other instanceof PaguId) ) return false;
         PaguId castOther = ( PaguId ) other; 

         return (this.getId()==castOther.getId() amp;amp; this.getRevisiId()==castOther.getRevisiId())
 amp;amp; (this.getRevisiId()==castOther.getRevisiId());
   }

   public int hashCode() {
         int result = 17;

         result = 37 * result   this.getId();
         result = 37 * result   this.getRevisiId();
         return resu<
   }   


}
  

Когда я пытаюсь сохранить это в базе данных, я получаю ошибку :

 org.hibernate.NonUniqueObjectException: a different object with the same    identifier value was already associated with the session:
  

— ОБНОВИТЬ—
Но изменение реализации с использованием EmbeddedId следующим образом

 public class Pagu  implements java.io.Serializable {


     private PaguId id;
     ...

     @EmbeddedId
@AttributeOverrides( {
    @AttributeOverride(name="id", column=@Column(name="id", nullable=false) ), 
    @AttributeOverride(name="revisiId", column=@Column(name="revisi_id", nullable=false) ) } )
public PaguId getId() {
    return this.id;
}

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

Он скомпилирован правильно, но выдал мне ошибку при сохранении модели.

 org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): id.model.Pagu
  

Комментарии:

1. Вы не должны использовать @Embeddable и @IdClass одновременно. Либо выберите использование: 1. @Embeddable в классе составного первичного ключа и @EmbeddedId в классе сущностей, либо 2. без аннотаций в классе составного первичного ключа и @IdClass на уровне класса сущностей с несколькими @Id аннотациями в самом классе сущностей (для полей).

2. Выполнение этого также сгенерировало исключение a different object with the same identifier value was already associated with the session: [id.go.model.Pagu#id.go..model.PaguId@5ae9] ошибка вида, которую я получил, если в @id нет @GeneratedValue

3. Я нашел ссылку для создания частичной генерации идентификатора docs.jboss.org/hibernate/annotations/3.5/reference/en /… но также есть предупреждение о том, что такая конструкция в корне неверна

4. возможно, вам будет интересно создать свой собственный механизм генерации идентификаторов. [ onjava.com/pub/a/onjava/2006/09/13 /… это позволит вам удалить @GeneratedValue аннотацию

Ответ №1:

Я не думаю, что возможно использовать GeneratedValue в составном ключе, вы должны выбрать либо составной ключ, либо один GeneratedValue-id.

Ответ №2:

вы должны удалить оба ваших ключа id и revisiId из вашего основного класса сущностей, поскольку он уже присутствует в @Embeddable, попробуйте и поделитесь своим ответом.

Комментарии:

1. Вы можете найти один рабочий пример на , довольно красиво объясненный.

2. можете ли вы сравнить свой код с тем, который упоминался в моем предыдущем комментарии ( j2eereference.com/2011/01 /… ).

3. Я обновил код, чтобы он соответствовал вашему примеру, и добавил @EmbeddableId. это исходная форма, когда я перепроектирую модель из базы данных с использованием netbeans

4. С помощью составного ключа вы должны указать свое собственное значение ( docs.jboss.org/hibernate/stable/core/reference/en-US/html /… )