Настойчивость отношения один ко многим - PullRequest
2 голосов
/ 24 июня 2010

Я использую Java EE 6. Просто хочу сначала выкинуть его туда
Вот отношения. A 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();

Однако, как только я попытаюсь добавить объект и принудительно ограничить ФК. Вещи начинают ломаться.

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, имеет поле CUSTOMER_FK, которое создается, когда я пытаюсь установить отношение один-ко-многим между CUSTOMER и FACILITY, но запрос никогда ничего не вставляет в это поле

Ответы [ 2 ]

2 голосов
/ 24 июня 2010

Сначала я получаю двойную сумму от той же вставки клиента "Университета Уэйк Форест" в таблицу 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();

Во-первых, предприятие ничего не знает о своем клиенте (это однонаправленная ассоциация, начиная с * 1018).* to Facitlity), поэтому JPA не может установить FK, отсюда и сообщение об ошибке.

Во-вторых, потому что вы каскадно все операций с Customer на Facilitycascade=CascadeType.ALL в аннотации @OneToMany) вам не нужно persist экземпляр facility.

Так что просто не вызывайте persist для экземпляра facilityПозвольте JPA каскадировать вещи из customer.

1 голос
/ 24 июня 2010

Вы получаете клиента с двойным именем, поскольку в столбце name нет уникального ограничения, поэтому при выполнении второго теста клиент с тем же именем снова добавляется. Добавьте unique=true к имени клиента, и столбец станет уникальным. Затем вы столкнетесь с проблемой, что вы не можете создать второго клиента с таким же именем.

Объект не требует явного сохранения, поскольку он также сохраняется каскадно при сохранении Клиента.

Фактически, вы также не можете сохранить объект напрямую, так как у него нет собственного стола. Используя @JoinColumn, вы удаляете использование таблицы соединения между Клиентом и Средством и помещаете внешний ключ клиента в таблицу Способности. Если вы удалите @JoinColumn, то вы увидите таблицу дополнительных соединений, например CUSTOMER_FACILITY, в которой хранится сопоставление клиентов с объектами. Затем вы можете сохранить объект самостоятельно.

...