2

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 
    ... 
} 

난 그냥이있는 경우, 그것은 잘 작동합니다. 나는이 최대한 빨리 시설을 추가하고 FK의 구속을 강제로 시도로, 그러나 내 데이터베이스

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

에 삽입 얻을 볼 수 있습니다. 일이 깨기 시작합니다.

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 고객의 고객 기록을 고객 테이블에 삽입합니다 (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 테이블은 내가 CUSTOMERFACILITY 사이에 일대 다 관계를 강제하려고 할 때 생성되는 필드 CUSTOMER_FK을 가지고 있지만 쿼리는 해당 필드에 아무것도 삽입하지 마십시오

+0

부수적으로, 당신은'시설 '에'equals'과'hashCode'를 구현해야합니다. –

+0

분명히 양방향 관계 여야합니다. 고마워 문제 해결. 도와 줘서 고마워. 모두들. 단방향에 대한 언급이 나에게 많은 도움이되기 때문에 파스칼에게 감사드립니다. 고마워요 –

답변

2

먼저 내가 같은 이중 얻을 Customer 기업의 name 그래서 아무것도이를 방지하지에 고객 테이블

음으로 고객 삽입, 당신이 어떤 고유성 제약 조건을 정의하지 않았다 "포레스트 대학 웨이크" (두 레코드 모두 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를 설정할 수 없으므로 오류 메시지가 표시됩니다.

둘째, 당신은 CustomerFacility로합니다 (@OneToMany 주석의 cascade=CascadeType.ALL 포함)에서 모든 작업을 계단식 있기 때문에, 당신은 persistfacility 인스턴스에 필요하지 않습니다.

따라서 facility 인스턴스에서 persist를 호출하지 말고 JPA가 customer에서 케스케이드하도록하십시오.

+0

내가 말하는 '고객'테이블에 중복 된 이름이 아닙니다. 한 번에'Wake Forest Univeristy'라는 2 개의 항목을 삽입하는 것입니다. 그래서 내가 1 안에 달린 후에, 고객의 내부에 아무것도 없다면, 나는 2 명의 entires가있을 것입니다. 이 중복은 고객을 만들려고 시도하는 경우 발생하지 않습니다. 내가 'Facility facility = new Facility()'를하자마자, 나는 그 중복을 얻었다. (나는 포스트의 끝 부분을 코딩하면서 이것에 대해 약간 설명한다.) –

+0

이제'em.persistent (facility)'주석은 문제를 해결하지 못합니다. 나는 여전히 복제본을 가지고 있으며, FACILITY 테이블에 아무것도 삽입하지 않습니다. 그러나 오류 로그를 살펴보면 : 호출 : INSERT INTO FACILITY (ID, NAME, STREET2, STREET1, ZIPCODE, STATE, CITY, COUNTRY) VALUES (?,?,?,?,?,?,?,?) => [2, Xia, null, null, null, null, null, null]', 내 FACILITY 테이블에 CUSTOMER와 CUSTOMER 사이에 일대 다 관계를 강제하려고 할 때 생성되는'CUSTOMER_FK' 필드가 있습니다. FACILITY이지만 쿼리는 그 필드에 아무 것도 삽입하지 않습니다. –

1

name 열에 고유 제한 조건이 없기 때문에 중복 이름이 지정된 고객을 얻습니다. 따라서 두 번째 테스트를 실행하면 동일한 고객을 다시 한 번 추가합니다. 고객 이름에 unique=true을 추가하면 해당 열은 고유하게 적용됩니다. 그런 다음 동일한 이름의 두 번째 고객을 생성 할 수 없다는 문제가 발생합니다.

시설을 명시 적으로 저장하지 않아도됩니다. 이는 고객을 저장할 때 계단식으로 저장되기 때문입니다.

사실 자체 테이블이 없기 때문에 시설을 직접 유지할 수도 없습니다. @JoinColumn을 사용하면 Customer와 Facility 간의 조인 테이블 사용을 제거하고 Customer 외래 키를 Facuility 테이블에 넣습니다. @JoinColumn을 제거하면 CUSTOMER_FACILITY와 같은 추가 조인 테이블이 표시됩니다.이 조인 테이블은 고객을 시설에 매핑하는 것을 저장합니다. 그런 다음 독립적으로 시설을 유지할 수 있습니다.

+0

그래서이 디자인에'em.persist (facility)'가 필요 없다는 뜻입니다. 그것은 계단식으로 연결되어야합니다, 맞습니까? 내가 말하는 '고객 (CUSTOMER)'표의 중복 이름이 아닙니다. 한 번에'Wake Forest Univeristy'라는 2 개의 항목을 삽입하는 것입니다. 그래서 만약 내가'CUSTOMER' 안에 아무것도 없다면, 1 번 실행 후에, 나는 2 명의 entires를 가질 것입니다. –

+0

나는'em.persist (시설)'을 꺼내서 문제를 해결하지 못했습니다. 어떤 생각인지 –