我正在通过使用组件(在JPA术语中使用Embeddables)来实现hibernate中的组合。我使用的是User
和Address
的简单示例。
在使用Hibernate 5.2时,每当我尝试在@Id
类中创建@Embeddable
时,hibernate都会抛出断言失败
在继承状态层次结构中找不到声明类
如果我删除@Id
注释并通过setter方法设置其值,则两个表都会正确填充。
根据一般数据库规则,每个表必须具有主键,即使两个或多个表的某些列之间存在引用关系。
我知道可以在@ElementCollection
到
@GenericGenerator(name="sequence-gen",strategy="sequence")
@CollectionId(columns = { @Column(name="JOIN_TB_PRI_KEY") }, generator = "sequence-gen", type = @Type(type="long"))
我感到困惑的是为什么我不能在地址类中使用@Id
。
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
}
地址类
@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();
}
}
}
答案 0 :(得分:0)
@ElementCollection 是元素的集合。它可以是基本类型的集合,也可以是 @Embeddable 元素(子实体)。所以这意味着这个子实体是主要实体的一部分,没有自己的生命周期。结果他们没有自己的id @Id 。
如果您需要提供自己的主ID,那么正确的方法是创建两个表 UserDetails 和 Address 。然后创建两个实体类@Entity和 @OneToMany 或 @ManyToOne 关系(取决于您的业务案例)。