为了账号安全,请及时绑定邮箱和手机立即绑定

ManyToMany 本身带有带有 EmbeddedId 的 AssociationTable

ManyToMany 本身带有带有 EmbeddedId 的 AssociationTable

吃鸡游戏 2021-11-11 16:19:52
在多对多关联期间,我在使用 Hibernate 时遇到了一些麻烦:/我想让一个用户拥有他的联系人。关联表用于包含关联的创建日期及其状态(例如活动、非活动等...)休眠版本:5.2.17弹簧靴:2.0.5我的班级用户:@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;@EmbeddedIdprivate AssocUserUserId id;@Column(name = "creation_date", nullable = false)private LocalDateTime creationDate;@Column(name = "status")@Enumerated(EnumType.STRING)private ContactStatusEnum status;}我的 EmbeddedId 类 AssocUserUserId :@Embeddablepublic 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: A Foreign keyrefering com.....AssocUserUser from com.....User 有错误的列数。应该是 2
查看完整描述

1 回答

?
杨__羊羊

TA贡献1943条经验 获得超7个赞

好吧,这个问题已经在Spring-Data-JPA ManyToMany 与额外列的关系中提出并回答,但我想它与自我引用有点不同。我不是所有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=?


查看完整回答
反对 回复 2021-11-11
  • 1 回答
  • 0 关注
  • 172 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信