2

我正在使用 Java EE 6。只是想先把它扔出去
。这就是关系。Acustomer可以有多个facility
Here is Customer Class

@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();

这是错误。首先,我将相同的“维克森林大学”客户插入 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表有一个字段,当我尝试强制andCUSTOMER_FK之间的一对多关系时创建该字段,但查询从未在该字段中插入任​​何内容CUSTOMERFACILITY

4

2 回答 2

2

首先,我将相同的“维克森林大学”客户插入 CUSTOMER 表的两倍

好吧,您没有nameCustomer实体定义任何唯一性约束,所以没有什么可以阻止这一点(尽管两条记录都有不同的 PK)。如果要强制 的唯一性name,请设置唯一约束:

@Column(unique=true)
String name;

错误代码之一是字段“customer_fk”没有默认值。

我认为注释行是“有罪的”:

tx.begin();
em.persist(customer);
//em.persist(facility); //DON'T DO THIS
tx.commit();

首先,设施对其客户一无所知(这是一个单向关联,从CustomerFacitlity),因此 JPA 无法设置 FK,因此出现错误消息。

其次,因为您将所有操作从Customerto级联Facilitycascade=CascadeType.ALL在注释中使用),所以@OneToMany您不需要实例。persistfacility

所以,只是不要在facility实例上调用持久化,让 JPA 从customer.

于 2010-06-24T18:23:07.747 回答
1

您得到了重复命名的客户,因为列上没有唯一约束name,因此运行第二个测试会再次添加相同的命名客户。添加unique=true到客户名称,该列将被强制为唯一。然后,您将遇到一个问题,即您无法创建具有相同名称的第二个客户。

Facility 不需要显式保存,因为当您保存 Customer 时,它也会级联保存。

事实上,您也不能直接持久化该设施,因为它没有自己的表。通过使用 a @JoinColumn,您可以删除 Customer 和 Facility 之间连接表的使用,并将客户外键放入 Facility 表中。如果您删除@JoinColumn,那么您将看到一个额外的连接表,例如 CUSTOMER_FACILITY,它存储客户到设施的映射。然后,您可以独立地持久化设施。

于 2010-06-24T18:06:14.330 回答