Reputation: 46482
I may be mixing up terms, but what I call a simple entity is something like Customer
or Product
, i.e., a thing having its own identity and for which I'm using an Integer id
.
A composed entity is something like CustomerProduct
, allowing to create an m:n mapping and associate some data with it. I created
class CustomerProduct extends MyCompositeEntity {
@Id @ManyToOne private Customer;
@Id @ManyToOne private Product;
private String someString;
private int someInt;
}
and I'm getting the message
Composite-id class must implement Serializable
which lead me directly to these two questions. I trivially could implement Serializable
, but this would mean to serialize Customer
and Product
as a part of CustomerProduct
and this makes no sense to me. What I'd need is a composite key containing two Integer
s, just like a normal key is just one Integer
.
Am I off the track?
If not, how can I specify this using just annotations (and/or code)?
Upvotes: 0
Views: 327
Reputation: 23562
You can use @EmbeddedId
and @MapsId
:
@Embeddable
public class CustomerProductPK implements Serializable {
private Integer customerId;
private Integer productId;
//...
}
@Entity
class CustomerProduct {
@EmbeddedId
CustomerProductPK customerProductPK;
@MapsId("customerId")
@ManyToOne
private Customer;
@MapsId("productId")
@ManyToOne
private Product;
private String someString;
private int someInt;
}
Upvotes: 0
Reputation: 383
Hibernate session objects need to be serializable, this implies all referenced objects must be serializable too. Even if your were using primitive types as a composite key, you need to add a serialization step.
You can use a composite primary key in Hibernate with the annotations @EmbeddedId
or @IdClass
.
With IdClass
you can do the follwing (assuming your entities use integer keys):
public class CustomerProduckKey implements Serializable {
private int customerId;
private int productId;
// constructor, getters and setters
// hashCode and equals
}
@Entity
@IdClass(CustomerProduckKey.class)
class CustomerProduct extends MyCompositeEntity { // MyCompositeEntity implements Serializable
@Id private int customerId;
@Id private int productId;
private String someString;
private int someInt;
}
You primary key class must be public and must have a public no-args constructor. It also must be serializable
.
You can also use @EmbeddedId
and @Embeddable
, which is a bit clearer and allows you to reuse the PK elsewhere.
@Embeddable
public class CustomerProduckKey implements Serializable {
private int customerId;
private int productId;
//...
}
@Entity
class CustomerProduct extends MyCompositeEntity {
@EmbeddedId CustomerProduckKey customerProductKey;
private String someString;
private int someInt;
}
Upvotes: 2