4

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

}
Yappie
  • 399
  • 2
  • 8
user973779
  • 87
  • 1
  • 1
  • 5
  • I think this question and answer will help: http://stackoverflow.com/questions/6405746/mapping-manytomany-with-composite-primary-key-and-annotation – danny.lesnik Sep 30 '11 at 20:44
  • 1
    Thanks for link that did not help as you can see I am trying to generate the id for one of the 3 columns which constitute the primary composite key .. At this point I am considering generating OrderID externally and setting it to the object which I don't like .. but not much traction on this post.. – user973779 Oct 04 '11 at 15:38
  • This might help: https://vladmihalcea.com/how-to-map-a-composite-identifier-using-an-automatically-generatedvalue-with-jpa-and-hibernate/ – JavaTec Feb 23 '18 at 15:25

4 Answers4

9

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 (i.e. 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 (i.e. persistence object collections).

ha9u63a7
  • 6,233
  • 16
  • 73
  • 108
  • Agreed until someone can give better answers – user973779 Nov 12 '12 at 21:42
  • @user973779 Unfortunately, it is what it is (not in a rude way, please don't get me wrong)...If you have a composite key, it means you don't the key to be managed by the IoC container (i mean Spring, but it could be the native ODBC container too). Conversely, having an auto-generated PK means that you are relying on the container....what I tried to do is go over my head and revolutionise how RDBMS work...:P...I don't know how good I managed to summarise, but you can get more opinions...we did a brainstorming in the office and this is what the conclusion was, pretty much! – ha9u63a7 Nov 12 '12 at 22:54
1

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.

Community
  • 1
  • 1
Ramsharan
  • 2,054
  • 2
  • 22
  • 26
1

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. e.g.

@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.

ImNomad
  • 51
  • 6
0

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.

Hari
  • 219
  • 4
  • 8