在ManyToMany关联期间,我在Hibernate方面遇到了一些麻烦: 我想让一个用户与其联系人联系。 关联表用于具有关联的creation_date及其状态(例如,活动,非活动等)
我的班级用户:
@Entity(name = "user")
public class User implements Serializable {
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "assoc_user_user", joinColumns = {@JoinColumn(name =
"id.myself.id")}, inverseJoinColumns = {@JoinColumn(name =
"id.contact.id")})
private List<AssocUserUser> contacts;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "assoc_user_user", joinColumns = {@JoinColumn(name =
"id.contact.id")}, inverseJoinColumns = {@JoinColumn(name =
"id.myself.id")})
private List<AssocUserUser> contactOf;
}
我的关联类AssocUserUser:
@Entity(name = "assoc_user_user")
public class AssocUserUser implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private AssocUserUserId id;
@Column(name = "creation_date", nullable = false)
private LocalDateTime creationDate;
@Column(name = "status")
@Enumerated(EnumType.STRING)
private ContactStatusEnum status;
}
我的EmbeddedId类AssocUserUserId:
@Embeddable
public class AssocUserUserId implements Serializable {
private static final long serialVersionUID = 1L;
@ManyToOne
@JoinColumn(name = "user_id_myself", nullable = false)
private User myself;
@ManyToOne
@JoinColumn(name = "user_id_contact", nullable = false)
private User contact;
}
我的错误:
由于:org.hibernate.AnnotationException:外键引用 com .....用户的com ..... AssocUserUser用户的错误编号 柱。应该是2
答案 0 :(得分:0)
好吧,这个问题已经在Spring-Data-JPA ManyToMany relationship with extra column上提出并回答了,但我想它与自我参考有所不同。我不是所有JoinTable
和JoinColumn
批注的忠实拥护者,只是因为它们通常是多余的,恕我直言,恕我直言,它意在更改默认值。我的答案不包括那些注释,因此请根据需要添加它们。请注意,对于Spring-Data-Jpa,您需要每个实体的存储库,因此您需要关联实体的存储库。这与JPA中的单个实体管理器不同。这会稍微影响您处理关联实体的方式。在这里,我们通过创建和保留新的AssocUserUser
实体来保留新的关系。
我完成课程的方式是:
@Entity
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy="myself")
private Set<AssocUserUser> contacts;
@Entity
public class AssocUserUser {
@EmbeddedId
private AssocUserUserId id = new AssocUserUserId();
@ManyToOne @MapsId("myselfId")
private User myself;
@ManyToOne @MapsId("contactId")
private User contact;
@SuppressWarnings("serial")
@Embeddable
public class AssocUserUserId implements Serializable {
private Long myselfId;
private Long contactId;
两个实体的和Repositories
public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u left outer join fetch u.contacts where u.id = :userId")
User getContactsForUser(@Param("userId") Long userId);
public interface AssocUserUserRepository extends JpaRepository<AssocUserUser, AssocUserUserId> {
如何创建关联
private void update() {
User user1 = new User();
User contact1 = new User();
userRepo.save(user1);
userRepo.save(contact1);
AssocUserUser assoc = new AssocUserUser();
assoc.setMyself(user1);
assoc.setContact(contact1);
assocUserUserRepo.save(assoc);
}
如何以Unidirectional
方式阅读关联
private void read() {
User me = new User();
me.setId(1L);
AssocUserUser assoc = new AssocUserUser();
assoc.setMyself(me);
List<AssocUserUser> contacts = assocUserUserRepo.findAll(Example.of(assoc));
System.out.println(contacts.size());
}
并以Bidirectional
的方式阅读关联:
private void readBi() {
User me = userRepo.getContactsForUser(1L);
System.out.println(me.getContacts().size());
}
与往常一样,查看日志:
create table assoc_user_user (contact_id bigint not null, myself_id bigint not null, primary key (contact_id, myself_id))
create table user (id bigint generated by default as identity, primary key (id))
alter table assoc_user_user add constraint FKaccetv956cu63fwiejjfrm0mi foreign key (contact_id) references user
alter table assoc_user_user add constraint FK1absxfuktrjnom8vwtjfqx5l0 foreign key (myself_id) references user
insert into user (id) values (null)
insert into user (id) values (null)
select assocuseru0_.contact_id as contact_1_0_0_, assocuseru0_.myself_id as myself_i2_0_0_ from assoc_user_user assocuseru0_ where assocuseru0_.contact_id=? and assocuseru0_.myself_id=?
select user0_.id as id1_1_0_ from user user0_ where user0_.id=?
select user0_.id as id1_1_0_ from user user0_ where user0_.id=?
insert into assoc_user_user (contact_id, myself_id) values (?, ?)
select assocuseru0_.contact_id as contact_1_0_, assocuseru0_.myself_id as myself_i2_0_ from assoc_user_user assocuseru0_ inner join user user1_ on assocuseru0_.myself_id=user1_.id where user1_.id=1
select user0_.id as id1_1_0_ from user user0_ where user0_.id=?
select user0_.id as id1_1_0_ from user user0_ where user0_.id=?
select user0_.id as id1_1_0_, contacts1_.contact_id as contact_1_0_1_, contacts1_.myself_id as myself_i2_0_1_, contacts1_.myself_id as myself_i2_0_0__, contacts1_.contact_id as contact_1_0_0__ from user user0_ left outer join assoc_user_user contacts1_ on user0_.id=contacts1_.myself_id where user0_.id=?
select user0_.id as id1_1_0_ from user user0_ where user0_.id=?