2008-10-28 7 views
16

Возможно ли в простых расширениях JPA или JPA + Hibernate объявлять составной ключ, где элемент составного ключа является последовательностью?JPA Composite Key + Sequence

Это мой композитный класс:

@Embeddable 
public class IntegrationEJBPk implements Serializable { 

    //... 


    @ManyToOne(cascade = {}, fetch = FetchType.EAGER) 
    @JoinColumn(name = "APPLICATION") 
    public ApplicationEJB getApplication() { 
     return application; 
    } 


    @Column(name = "ENTITY", unique = false, nullable = false, insertable = true, updatable = true) 
    public String getEntity() { 
     return entity; 
    } 

    @GeneratedValue(strategy = GenerationType.AUTO, generator = "INTEGRATION_ID_GEN") 
    @SequenceGenerator(name = "INTEGRATION_ID_GEN", sequenceName = "OMP_INTEGRATION_CANONICAL_SEQ") 
    @Column(name = "CANONICAL_ID", unique = false, nullable = false, insertable = true, updatable = true) 
    public String getCanonicalId() { 
     return canonicalId; 
    } 

    @Column(name = "NATIVE_ID", unique = false, nullable = false, insertable = true, updatable = true) 
    public String getNativeId() { 
     return nativeId; 
    } 

    @Column(name = "NATIVE_KEY", unique = false, nullable = false, insertable = true, updatable = true) 
    public String getNativeKey() { 
     return nativeKey; 
    } 

    //... 
} 

Я уже о значениях application, entity, nativeId и nativeKey. Я хочу, чтобы построить объект, как показано ниже:

IntegrationEJB i1 = new IntegrationEJB(); 
i1.setIntegrationId(new IntegrationEJBPk()); 
i1.getIntegrationId().setApplication(app1); 
i1.getIntegrationId().setEntity("Entity"); 
i1.getIntegrationId().setNativeId("Nid"); 
i1.getIntegrationId().setNativeKey("NK"); 

И когда я называю em.persist(i1), я хочу, чтобы canonicalId генерируется и интеграция вставляется.

Возможно ли это? Если да, то какой простой способ? (Я предпочитаю не использовать ключи, предоставленные приложением или собственный sql).

ответ

3

Я считаю, что это невозможно с помощью простого JPA.

+0

Возможно. Единственный способ, который я нашел, требует, чтобы части Id не были вставлены или обновляемы. Требуется уточнить устаревший пост, так как это лучший результат в результатах поиска. – Valchris 2011-05-03 02:33:47

1

Try так:

@TableGenerator(name = "canonicalKeys", allocationSize = 1, initialValue = 1) 
@GeneratedValue(strategy = GenerationType.TABLE, generator = "canonicalKeys") 
@Column(name = "CANONICAL_ID", unique = false, nullable = false, insertable = true, updatable = true) 
public String getCanonicalId() { 
    return canonicalId; 
} 

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

+0

Мне нужно использовать последовательность, так как я не могу изменить мою модель базы данных. – 2008-11-10 10:41:24

1

Я замечаю, что это здание вашего сложного первичного ключа, такого как example. В то время как я был тыкая в подобных проблемах в моей базе данных, я подумал, что, может быть, вы могли бы назвать SQL непосредственно, как:

select nextval ('hibernate_sequence')

Я полагаю, что было бы обманом, хотя ;-)

2

Использования @GeneratedValue для составных ПК не указывается с помощью спецификации JPA 2.

Из спецификации JPA:

11.1.17 GeneratedValue Аннотация

В аннотации GeneratedValue обеспечивает спецификации стратегий для генерации значений первичных ключей. Аннотацию GeneratedValue может применяться к свойству первичного ключа или к полю объекта или сопоставленного суперкласса в сочетании с аннотацией Id . [97] Использование аннотации GeneratedValue - это только , которые необходимо поддерживать для простых первичных ключей. Использование аннотации GeneratedValue не поддерживается для производных первичных ключей.

Обратите внимание, что в другом случае, вы можете иметь родительский объект с помощью простого ПК (@Id), который использует @GeneratedValue, а затем дочерний объект, который имеет композитные ПК, который включает в себя сгенерированный идентификатор из parent, плюс еще один столбец.

  • Дайте ребенку отношение @ManyToOne к родительскому объекту, чтобы он наследовал сгенерированный идентификатор в столбце FK.
  • Затем дайте ребенку составной PK, через @IdClass, указанный для объекта, плюс два столбца @Id внутри объекта.
@Entity 
public class ParentEntity { 
 @Id 
     @GenerateValue(IDENTITY) // If using DB auto-increment or similar 
     int id; 

     // ... 
} 
@Entity 
@IdClass(ChildId.class) 
public class ChildEntity { 
    // The child table will have a composite PK: 
    // (parent_ID, child_name) 
     @Id 
     @ManyToOne 
     int parentEntity; 
 @Id 
     String childName; 

     String favoriteColor; // plus other columns 

     // ... 

} 
// child Id attributes have the same name as the child entity 
// however the types change to match the underlying PK attributes 
// (change ParentEntity to int) 
public class ChildId implements Serializable { 
 int parentEntity; 
     String childName; 

     public ChildId() { //... } 

     // Add extra constructor & remove setter methods so Id objects are immutable 
     public ChildId(int parentEntity, String childName) { //... } 


     public int getParentEntity() { //... } 
     // make Id objects immutable: 
     // public void setParentEntity(int parentEntity) { //... } 
     public String getChildName() { //... } 
     // public void setChildName(String childName) { //... } 
}