简体   繁体   中英

Hibernate composite key id generator

I have my entities as below. My data model enforces below and I cannot change referential itegrity. So I am stuck with a composite key. I want to autogenerate/use some generator for orderId

Yes I have read below. http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#entity-mapping-identifier

I donot want to manage the id generation process as above recommends application generating the orderId.

How to make the partial id generator work.. what are my options..would greatly appreciate some thoughts by experts.

@Entity
@Table(name = "Orders", uniqueConstraints = @UniqueConstraint(columnNames = {"partner_ID", "order_ident" }))
public class Order  {

private OrderId id;

public Order() {
}


@EmbeddedId
@AttributeOverrides({
        @AttributeOverride(name = "partnerId", column = @Column(name = "partner_ID", nullable = false)),
        @AttributeOverride(name = "employeeId", column = @Column(name = "employee_ID", nullable = false)),
        @AttributeOverride(name = "orderId", column = @Column(name = "order_ID", nullable = false)) })
public OrderId getId() {
    return this.id;
}

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


}


@Embeddable
public class OrderId extends FactObject {

private int partnerId;
private int employeeId;
private int orderId;

public OrderId() {
}

public OrderId(int partnerId, int employeeId, int orderId) {
    this.partnerId = partnerId;
    this.employeeId = employeeId;
    this.orderId = orderId;
}

@Column(name = "partner_ID", nullable = false)
public int getpartnerId() {
    return this.partnerId;
}

public void setpartnerId(int partnerId) {
    this.partnerId = partnerId;
}

@Column(name = "employee_ID", nullable = false)
public int getemployeeId() {
    return this.employeeId;
}

public void setemployeeId(int employeeId) {
    this.employeeId = employeeId;
}

@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE")
@Column(name = "order_ID",insertable=false, nullable=false,  updatable=false)
public int getOrderId() {
    return this.orderId;
}

public void setOrderId(int orderId) {
    this.orderId = orderId;
}

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

    return (this.getpartnerId() == castOther.getpartnerId())
            && (this.getemployeeId() == castOther.getemployeeId())
            && (this.getOrderId() == castOther.getOrderId());
}

public int hashCode() {
    int result = 17;

    result = 37 * result + this.getpartnerId();
    result = 37 * result + this.getemployeeId();
    result = 37 * result + this.getOrderId();
    return result;
}

}

I have been hovering over all the possible links on World Wide Websites and trying to find why you cannot use @GeneratedValue with @EmbeddedId or @IdClass (ie composite PKs). The reason is that you just CANNOT. An explanation provided here might help you feel a bit better: JAVA.NET/GLASSFISH

Composite PKs are ASSIGNMENT-based not GENERATION-based. Therefore, any @GeneratedValue stuff are not supposed to work with them. I am also having problem in my project and I think there is no other way, EXCEPT:

If you know that your @GeneratedValue ID is always unique in context of your domain (for example, your database) you don't need to use composite PK and have some internal checks to determine the uniqueness of your records (ie persistence object collections).

I think this question of stackoverflow might help you. Although it was asked for different purpose, it has the answer you might need. It has used both composite primary key and generation type.

Isn't using @IdClass a solution? One can use @Id on each of the columns that form the primary key and @GeneratedValue and @SequenceGenerator on the @Id column that should be generated by a sequence.

Generation strategy of composite primary key can be managed by @IdClass. Annotate the class with @IdClass for which you need composite pk. Annotate the fields that make for composite pk with @Id and @GeneratedValue. This works. eg

@Entity
@IdClass(B.class)
Class A {
    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    private int i;
    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    private int j;

    private String variable;
}

Class B implements Serializable{
    private int i;
    private int j;

    public int geti(){return i;}
    public int getj(){return j;}
}

In this example, combination of i and j will work as composite primary key for A. Their values are auto generated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM