[英]Bidirectional many-to-one with subclasses and generics
我正在努力實現兩個類層次結構之間的雙向多對一映射。
我有以下內容:
具有子類AQueue
, BQueue
, CQueue
超類Queue
。 具有子類AElement
, BElement
和CElement
超類Element
。
AQueue
具有列表AElement
, BQueue
具有列表BElement
,等等, AElement
有AQueue
等。
我已經嘗試過這樣的事情:
@Entity
@Inheritance(strategy InheritanceType.SINGLE_TABLE)
public abstract class Queue<T extends Element> {
@OneToMany(mappedBy="queue")
private List<T> elements = new ArrayList<>();
//...
}
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Element<T extends Element> {
@ManyToOne
@JoinColumn("queue_id")
private Queue<T> queue;
}
只是讓Hibernate
抱怨mappedBy reference an unknown target entity property
。
有沒有一種方法可以使用泛型在超類中映射這種關系,還是我必須選擇每個子類對保持一個關系?
這是一個對我有用的Spring Boot測試(跳過樣板)(Hibernate 5.0):
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.transaction.Transactional;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.*;
@SpringBootTest
@RunWith(SpringRunner.class)
public class JpaTest {
@Autowired
private EntityManager em;
@Test
@Transactional
public void test() {
QueueA queueA = new QueueA(1L);
ElementA elementA = new ElementA(1L, queueA);
queueA.getElements().add(elementA);
em.persist(queueA);
em.persist(elementA);
QueueB queueB = new QueueB(2L);
ElementB elementB = new ElementB(2L, queueB);
queueB.getElements().add(elementB);
em.persist(queueB);
em.persist(elementB);
List queues = em.createQuery("SELECT q FROM Queue q").getResultList();
assertThat(queues).containsOnly(queueA, queueB);
List elements = em.createQuery("SELECT e FROM Element e").getResultList();
assertThat(elements).containsOnly(elementA, elementB);
}
}
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
abstract class Queue<T extends Element<T>> {
@Id
private Long id;
@OneToMany(mappedBy = "queue", targetEntity = Element.class)
private List<T> elements = new ArrayList<>();
public Queue(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<T> getElements() {
return elements;
}
public void setElements(List<T> elements) {
this.elements = elements;
}
}
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
abstract class Element<T extends Element<T>> {
@Id
private Long id;
@ManyToOne(targetEntity = Queue.class)
private Queue<T> queue;
public Element(Long id, Queue<T> queue) {
this.id = id;
this.queue = queue;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Queue<T> getQueue() {
return queue;
}
public void setQueue(Queue<T> queue) {
this.queue = queue;
}
}
@Entity
class QueueA extends Queue<ElementA> {
public QueueA(Long id) {
super(id);
}
}
@Entity
class ElementA extends Element<ElementA> {
public ElementA(Long id, Queue<ElementA> queue) {
super(id, queue);
}
}
@Entity
class QueueB extends Queue<ElementB> {
public QueueB(Long id) {
super(id);
}
}
@Entity
class ElementB extends Element<ElementB> {
public ElementB(Long id, Queue<ElementB> queue) {
super(id, queue);
}
}
要解決的重要問題是:
@OneToMany/@ManyToOne
關系中設置targetEntity
。 否則,Hibernate不能僅從泛型字段中確定確切的引用類。 在這里,通過指定targetEntity = Element.class
/ targetEntity = Queue.class
我們說的是希望Hibernate將其映射到整個實體類層次結構。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.