views:

2807

answers:

3

Hi,

Is it possible in plain JPA or JPA+Hibernate extensions to declare a composite key, where an element of the composite key is a sequence?

This is my composite class:

@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;
    }

    //...
}

I already supply the values for application, entity, nativeId and nativeKey. I want to construct an entity like the one below:

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

And when I call em.persist(i1), I want that the canonicalId is generated and the integration is inserted.

Is this possible? If so, what's the simple way? (I prefer not to use application-provided keys or native sql).

A: 

Try like this:

@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;
}

In this way instead of using a sequence you can use a table.

sakana
I have to use a sequence, since I cannot change my database model.
Miguel Ping
A: 

I believe that this is not possible with plain JPA.

Miguel Ping
A: 

I notice that it appears your building a composite primary key like this example. While I was poking at a similar problem in my own database I wondered if maybe you could call the sql directly like:

select nextval ('hibernate_sequence')

I suppose that would be cheating though ;-)

Petriborg