我正在使用Java EE 6.只是想先把它扔出去
这是关系。 customer
可以有多个facility
这是客户类
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="CUSTOMER_FK", nullable=false)
private List<Facility> facilities;
public Customer(){
facilities = new ArrayList<Facility>();
}
public Customer(Long id, String name, List<Facility> facilities) {
this.id = id;
this.name = name;
this.facilities = facilities;
}
//set and get method
...
public void addFacility(Facility facility){
this.facilities.add(facility);
}
}
这是设施类
@Entity
public class Facility {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
public Facility(){}
public Facility(Long id, String name, Address address, List<Project> project) {
this.id = id;
this.name = name;
}
//Set and get method
...
}
现在主要是如果我有这个,那么它工作正常。我可以看到这个插入我的数据库
Customer customer = new Customer();
customer.setName("Wake Forest University");
EntityManagerFactory emf = Persistence.createEntityManagerFactory("EntityLibraryPU");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
em.persist(customer);
tx.commit();
然而,只要我尝试添加设施并强制FK约束。事情开始破裂。
Customer customer = new Customer();
customer.setName("Wake Forest University");
Facility facility = new Facility();
facility.setName("Xia");
customer.addFacility(facility);
EntityManagerFactory emf = Persistence.createEntityManagerFactory("EntityLibraryPU");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
em.persist(customer);
tx.commit();
这是错误。首先,我得到同一个“Wake Forest University”客户插入CUSTOMER表的两倍(不name
属性未设置为唯一,它是一次将两个条目插入数据库)。但是,没有任何内容可以插入到我的FACILITY表中。知道为什么吗?其中一个错误代码是Field 'customer_fk' doesn't have a default value
。也许这可以暗示你们一点点。我不知道。当我查看错误日志:Call: INSERT INTO FACILITY (ID, NAME, STREET2, STREET1, ZIPCODE, STATE, CITY, COUNTRY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)bind => [2, Xia, null, null, null, null, null, null]
时,我的FACILITY
表中有一个字段CUSTOMER_FK
,当我尝试强制{{1}之间的一对多关系时创建该字段CUSTOMER
}和FACILITY
,但查询永远不会在该字段中插入任何内容
答案 0 :(得分:2)
首先,我将同一个“Wake Forest University”客户插入CUSTOMER表中的两倍
好吧,你没有在name
实体的Customer
上定义任何唯一性约束,所以没有什么能阻止这种情况(两个记录都有不同的PK)。如果要强制name
的唯一性,请设置唯一约束:
@Column(unique=true)
String name;
其中一个错误代码是字段'customer_fk'没有默认值。
我认为评论的行是“有罪”:
tx.begin();
em.persist(customer);
//em.persist(facility); //DON'T DO THIS
tx.commit();
首先,该设施对其客户一无所知(这是一个单向关联,从Customer
到Facitlity
),因此JPA无法设置FK,因此错误消息。
其次,因为您正在将{strong>所有操作从Customer
级联到Facility
(cascade=CascadeType.ALL
注释中的@OneToMany
,您不需要persist
facility
实例。
所以,只是不要在facility
实例上调用persist,让JPA从customer
级联内容。
答案 1 :(得分:1)
您获得了重复命名的客户,因为name
列上没有唯一约束,因此运行第二个测试会再次添加相同的命名客户。将unique=true
添加到客户名称,该列将被强制为唯一。然后,您将遇到无法创建具有相同名称的第二个客户的问题。
不需要明确保存工具,因为在您保存客户时也会以级联方式保存工厂。
事实上,你也不能直接坚持设施,因为它没有自己的桌子。通过使用@JoinColumn
,您可以删除Customer和Facility之间的连接表的使用,并将客户外键放在Facuility表中。如果删除@JoinColumn,那么您将看到一个像CUSTOMER_FACILITY这样的附加连接表,它存储客户到设施的映射。然后,您可以独立持有设施。