I am working on achieving composition in hibernate through the use of components (Embeddables in JPA terminology). I am using simple example of User
and Address
.
While using Hibernate 5.2, whenever I am trying to create an @Id
in @Embeddable
class, hibernate is throwing Assertion Failure
Declaring class is not found in the inheritance state hierarchy
If I remove the @Id
annotation and set its value through setter method, both the tables are getting populated correctly.
As per general database rules, every table must have a primary key, even if there exist a referential relationship between some columns of two or more tables.
I know that a primary key can be created on the join table for an @ElementCollection
through
@GenericGenerator(name="sequence-gen",strategy="sequence")
@CollectionId(columns = { @Column(name="JOIN_TB_PRI_KEY") }, generator = "sequence-gen", type = @Type(type="long"))
What I am confused about is why cannot I just use an @Id
in the Address class.
UserDetails Class
@Entity
@Table(name = "USER_DETAILS")
public class UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int userId;
private String userName;
@ElementCollection
@JoinTable(name = "USER_ADDRESS", joinColumns = @JoinColumn(name = "REFERRED_USER_ID"))
private Collection<Address> listOfAddress = new ArrayList<>();
// accessor and mutator methods
}
Address Class
@Embeddable
public class Address {
@Id // throws Assertion Failure while using it, else runs correctly
@GeneratedValue(strategy = GenerationType.AUTO)
private int addressPrimaryKey;
@Column(name = "STREET_NAME")
private String street;
@Column(name = "CITY_NAME")
private String city;
@Column(name = "STATE_NAME")
private String state;
@Column(name = "ZIP")
private String pinCode;
// accessor and mutator methods
}
HibernateUtil Class
public class HibernateUtil {
public static void main(String[] args) {
Address addr1 = new Address();
addr1.setStreet("Street 1");
addr1.setCity("City 1");
addr1.setState("State 1");
addr1.setPinCode("Zip 1");
addr1.setAddressPrimaryKey(100); // this value should be auto generated
Address addr2 = new Address();
addr2.setStreet("Street 2");
addr2.setCity("City 2");
addr2.setState("State 2");
addr2.setPinCode("Zip 2");
addr2.setAddressPrimaryKey(200); // this value should be auto generated
UserDetails user1 = new UserDetails();
user1.setUserName("First User");
user1.getListOfAddress().add(addr1);
user1.getListOfAddress().add(addr2);
UserDetails user2 = new UserDetails();
user2.setUserName("Second User");
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.save(user1);
session.save(user2);
tx.commit();
}
catch (Exception e) {
if (tx != null) {
tx.rollback();
}
throw e;
}
finally {
session.close();
}
}
}