簡體   English   中英

如何在 Spring JPA 中將一個實體與多個實體連接?

[英]How to connect one entity with more than one entity in Spring JPA?

我在理解如何在一個屬性中將一個實體與其他實體聯系起來時遇到了一些問題。 這不是典型的 OneToMany 關系,我說的是我需要在我的應用程序中實現投訴功能的情況: User可以投訴幾個不同的實體( QuestionAnswerComment或另一個User ),因此Complain實體將具有模式關系像: 圖式

其中 User 連接為一對多到user_id ,多對一連接到entity_id (圖像中的1**1 )。

所以,我嘗試使用參數化的 class Complain來實現這個( BaseComplain是空類):

Complain.java

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@Entity
@Table(name = "complains")
public class Complain<T extends BaseComplain> {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;


    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false)
    private User user_id;

    @ManyToOne
    @JoinColumn(name = "entity_id", nullable = false)
    private T entity_id;

    @Column
    @Temporal(TemporalType.TIMESTAMP)
    private Date created_on;

}

User.java

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@Entity
@Table(name = "users")
public class User extends BaseComplain {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @OneToMany(mappedBy = "user_id", orphanRemoval = true, fetch = FetchType.LAZY)
    @ToString.Exclude
    private Set<Complain<BaseComplain>> author_complains;

    @OneToMany(mappedBy = "entity_id", orphanRemoval = true, fetch = FetchType.LAZY)
    @ToString.Exclude
    private Set<Complain<User>> complains;

    <...other stuff...>
}

Question.java (所有實體具有相同的關系實現):

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@Entity
@Table(name = "questions")
public class Question extends BaseComplain {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "entity_id", orphanRemoval = true, fetch = FetchType.LAZY)
    @ToString.Exclude
    @JsonManagedReference
    private Set<Complain<Question>> complains;
    
    <...other stuff...>
}

但它導致(格式化):

org.hibernate.AnnotationException: 
Property com.*.*.Entities.Complain.entity_id has an unbound type and no explicit target entity.
Resolve this Generic usage issue or set an explicit target attribute (eg @OneToMany(target=)
or use an explicit @Type...

我可以添加所有堆棧跟蹤,但只有典型的 spring 應用程序異常( Bean creation errorembedded Tomcat exception )。

所以問題是——有沒有辦法只使用 JPA 的“基本”功能來實現這個邏輯?

可能,我對@MappedSuperclass的用法有一些想法,但仍然需要您的幫助。

這個怎么樣——看起來你在一定程度上已經嘗試過了; 這個想法是Complaint是一個抽象的基本實體,因此它可以與它有關系,但具體的實現是問題,答案等。要有一個基表和每個投訴類型分開的基表,請使用@Inheritance(strategy = InheritanceType.JOINED) 並使用不同於它們鏈接到的實體的具體投訴類型,例如QuestionComplaintQuestion 所以:

@Entity
@Table(name = "complaints")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Complaint {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false)
    private User user;

    @Column
    @Temporal(TemporalType.TIMESTAMP)
    private Date created_on;
}

用戶又與一組Complaint對象相關,但不是Complaint本身(沒有意義,是嗎?)

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @OneToMany(mappedBy = "user_id", orphanRemoval = true, fetch = FetchType.LAZY)
    @ToString.Exclude
    private Set<Complaint> complaints;
}

以及具體的Complaint實例:

@Entity
@Table(name = "question_complaints")
@PrimaryKeyJoinColumn(name = "id")
public class QuestionComplaint extends Complaint {
    @ManyToOne(fetch = FetchType.LAZY)
    private Question question
}

該實體表示從ComplaintQuestion的鏈接。 代表“問題”的Question實體,無論是否附加了投訴,都可以選擇與QuestionComplaint建立關系:

@Entity
@Table(name = "questions")
public class Question {
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "question")
    private List<QuestionComplaint> complaints;
}

現在我期望的用法是:

  1. 用戶提出的投訴是什么? - User.getComplaints()將從所有已知子類型中獲取一個 UNION ALL 投訴
  2. 問題(答案等)的抱怨是什么? - question.getComplaints()知道只從表question_complaints中獲取記錄
  3. 用戶 x 對問題 y 提出了哪些投訴? - SELECT c FROM QuestionComplaint c WHERE c.user.id =:x AND c.question.id =:y

首先,在 java Generic Types can't deteminable in runtime ,所以JPA不能確定從哪個table獲取,所以它會throw Exception

其次你的數據庫設計是錯誤的, Complain表不會連接到QuestionAnswerQuestionAnswer需要連接Complain 像:

Quesiton -|
          v
          ---> Complain ---> User
          ^
Answer   -|

或者您需要將兩個字段添加到Complain表中,例如questionIdanswerId

Q u e s i t o n    A n s w e r 
       ^               ^
       |               |
  (questionID)     (answerId)    
       |               |
       +-----------Complain ---> User

一域二外表不好專門為JPA設計的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM