我在图表中使用了以下类,因此可以有父母和孩子:
@Entity(name = "PedagogicalNeed")
@Table(name = "PedagogicalNeed")
public class PedagogicalNeedEntity extends AbstractEntity implements PedagogicalNeed {
private String name;
private String description;
@ManyToMany(targetEntity = PedagogicalNeedEntity.class, fetch = FetchType.LAZY)
private Set<PedagogicalNeed> parents = new HashSet<PedagogicalNeed>(0);
@ManyToMany(targetEntity = PedagogicalNeedEntity.class, fetch = FetchType.LAZY)
private Set<PedagogicalNeed> children = new HashSet<PedagogicalNeed>(0);
...
}
超类AbstractEntity
用于定义@Id
字段:
@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
...
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
...
}
我有以下请求,应该返回&#34; parent&#34;收集是空的。
@Query("SELECT pn FROM PedagogicalNeed pn WHERE pn.parents IS EMPTY")
Iterable<PedagogicalNeedEntity> findRoots();
我的问题是,当执行此请求时,我得到以下&#34; NOT NULL约束违规&#34;:
Caused by: org.hsqldb.HsqlException: integrity constraint violation: NOT NULL check constraint; SYS_CT_10102 table: PEDAGOGICALNEED_PEDAGOGICALNEED column: PARENTS_ID
问题:我如何返回没有父母的实体?
更新:生成的架构如下:
CREATE MEMORY TABLE PUBLIC.PEDAGOGICALNEED(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,DESCRIPTION VARCHAR(255),NAME VARCHAR(255))
ALTER TABLE PUBLIC.PEDAGOGICALNEED ALTER COLUMN ID RESTART WITH 1
CREATE MEMORY TABLE PUBLIC.PEDAGOGICALNEED_PEDAGOGICALNEED(
PEDAGOGICALNEED_ID BIGINT NOT NULL,
PARENTS_ID BIGINT NOT NULL,
CHILDREN_ID BIGINT NOT NULL,
PRIMARY KEY(PEDAGOGICALNEED_ID,CHILDREN_ID),
CONSTRAINT FK_GSX50JH17YMGUMDQ7ADD0Y0Y5 FOREIGN KEY(PARENTS_ID) REFERENCES PUBLIC.PEDAGOGICALNEED(ID),
CONSTRAINT FK_L6QY3L7AMTRVX1O62WVS6C9X8 FOREIGN KEY(PEDAGOGICALNEED_ID) REFERENCES PUBLIC.PEDAGOGICALNEED(ID),
CONSTRAINT FK_EHV0QET4GVHBX733YJV6Q9KQD FOREIGN KEY(CHILDREN_ID) REFERENCES PUBLIC.PEDAGOGICALNEED(ID))
我不理解这种映射,为什么有一张表&#34; PEDAGOGICALNEED_PEDAGOGICALNEED&#34;三个领域? PedagogicalNeedEntity与其父母之间的联系与同一实体及其子女之间的联系无关。所以应该有两个表而不仅仅是一个,每个表只有两列:
答案 0 :(得分:2)
PEDAGOGICALNEED_PEDAGOGICALNEED
之间多对多的数据库表PedagogicalNeedEntity
包含一个永不填充的列PEDAGOGICALNEED_ID
。
在PedagogicalNeedEntity中为ID列提供一个列定义(伪代码):
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
您可以自己提供ID(在保留实体之前)或使用生成的id值。
重要:为避免冗余,您不应在两种关系上使用@JoinTable
。在一个关系上使用@JoinTable
,在另一个关系上使用mappedBy
。
一个简单的例子,展示了如何创建这样一个节点网络#34; (使用Hibernate 4.3.8和Derby 10.9.1.0测试):
@Entity
public class Node {
@Id
public int id;
public String nodeName;
@ManyToMany
@JoinTable(name="relationships")
public List<Node> parents;
@ManyToMany(mappedBy="parents")
public List<Node> children;
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistenceUnit");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
entityManager.persist(new Node());
transaction.commit();
entityManager.close();
}
}
这将创建两个表:
答案 1 :(得分:1)
这不是由查询引起的异常。它必须是在查询之前触发的持久操作的例外。
持久性提供程序必须在执行查询之前刷新所有dml语句。
PEDAGOGICALNEED_ID列在数据库中不能为空,但您没有为该列提供值。
查询看起来很好。
答案 2 :(得分:1)
更新:这不起作用,请参阅了解如何获取单个联接表的最佳答案。
问题解决了!我只需要用“
”指定“连接表”的名称@ManyToMany(targetEntity = PedagogicalNeedEntity.class, fetch = FetchType.LAZY)
@JoinTable(name="PedagogicalNeed_parents")
private Set<PedagogicalNeed> parents = new HashSet<PedagogicalNeed>(0);
@ManyToMany(targetEntity = PedagogicalNeedEntity.class, fetch = FetchType.LAZY)
@JoinTable(name="PedagogicalNeed_children")
private Set<PedagogicalNeed> children = new HashSet<PedagogicalNeed>(0);
感谢您的帮助!