Сохранить объект PK с помощью JPA (ManyToMany) - PullRequest
0 голосов
/ 24 августа 2011

Пожалуйста, измените название, если вы знаете лучший, потому что я действительно не знаю, как выразить проблему.

У меня есть три класса:

@Entity
public class User {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 @Column(name = "id")
 private Integer id;

 @NotNull
 @Size(min = 1, max = 45)
 @Column(name = "name")
 private String name;

 @JoinTable(name = "usuer_has_contact", joinColumns = {
     @JoinColumn(name = "user_id", referencedColumnName = "id")}, inverseJoinColumns = {
     @JoinColumn(name = "contact_id", referencedColumnName = "id")})
 @ManyToMany(cascade = CascadeType.ALL)
 private List<Contato> contactList;

 //Getters and Setters

}

DB Table:
Table Name: User
Columns: id (int pk), name (varchar(45) not null).

@Entity
private class Contact {

 @EmbeddedId
 protected UserHasContact userHasContact;

 @NotNull
 @Size(min = 1, max = 45)
 @Column(name = "value")
 private String value;

 @ManyToMany(mappedBy = "contactList")
 private List<User> userList;

 //Getters and Setters

}

DB Table:
Table Name: Contact
Columns: id (int pk), value (varchar(45) not null).

@Embeddable
private class UserHasContact {

 @NotNull
 @Column(name = "id")
 private Integer id;

 //Getters and Setters

}

DB Table:
Table Name: UserHasContact
Columns: userId (int pk), contactId (int pk).

То, что я пытаюсь сделать, это сохранять все, когда я сохраняю самого пользователя.Например:

User user = new User();
user.setContactList(new ArrayList<Contact>());

Contact contact = new Contact();
contact.setValue("555-5555");

user.getContactList().add(contact);

// Here I'd call another class, passing User so it would only do a
// entityManager.persist(user), and it would persist it all and
// take care of all tables for me. What I don't want to do is to
// fill up the values myself, I want let JPA do it for me.

Я ожидал сохранить после этого, но он говорит, что contactId имеет значение NULL и не может быть NULL.Что я могу сделать?

1 Ответ

1 голос
/ 24 августа 2011

Почему вы создаете встраиваемый класс UserHasContact для хранения только одного целого числа? Вы делаете это сложнее, чем необходимо. Просто используйте Integer ID в качестве первичного ключа контакта. Это, однако, не является причиной вашей проблемы.

Вы пытаетесь сохранить пользователя, содержащего контакт в своем списке контактов. Идентификатор вашего контакта не генерируется автоматически, и вы не присваивали ему никакого идентификатора. Как JPA может сохранить этот контакт в базе данных? Более того, вы не сохранили контакт, поэтому он временный.

Вы должны

  • либо назначьте идентификатор контакту, либо аннотируйте его, чтобы он автоматически генерировался
  • сохранить контакт, а также пользователя

Вот код для контактного лица:

@Entity
private class Contact {
 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY) // this makes the ID auto-generated
 @Column(name = "id")
 private Integer id;

 @NotNull
 @Size(min = 1, max = 45)
 @Column(name = "value")
 private String value;

 @ManyToMany(mappedBy = "contactList")
 private List<User> userList;

 //Getters and Setters
}

А в коде, где создаются пользователь и контакт:

User user = new User();
user.setContactList(new ArrayList<Contact>());

entityManager.persist(user);

Contact contact = new Contact();
contact.setValue("555-5555");

entityManager.persist(contact);

user.getContactList().add(contact);
// you should also make sure that the object graph is consistent, so
// the following line should lso be added, (though not strictly necessary)
contact.getUserList().add(user);
...