我在创建自定义查询时遇到问题。
这就是实体:
@Entity
public class ApplicationProcess {
@CollectionOfElements
private Set<Template> defaultTemplates;
//more fields
}
和Template.java
@Embeddable
@EqualsAndHashCode(exclude={"used"})
public class Template implements Comparable<Template> {
@Setter private ApplicationProcess applicationProcess;
@Setter private Boolean used = Boolean.valueOf(false);
public Template() {
}
@Parent
public ApplicationProcess getApplicationProcess() {
return applicationProcess;
}
@Column(nullable = false)
@NotNull
public String getName() {
return name;
}
@Column(nullable = true)
public Boolean isUsed() {
return used;
}
public int compareTo(Template o) {
return getName().compareTo(o.getName());
}
}
我想创建一个更新语句。我试过这两个:
int v = entityManager.createQuery("update ApplicationProcess_defaultTemplates t set t.used = true " + "WHERE t.applicationProcess.id=:apId").setParameter("apId", ap.getId())
.executeUpdate();
ApplicationProcess_defaultTemplates is not mapped [update ApplicationProcess_defaultTemplates t set t.used = true WHERE t.applicationProcess.id=:apId]
我试过了
int v = entityManager.createQuery("update Template t set t.used = true " + "WHERE t.applicationProcess.id=:apId").setParameter("apId", ap.getId())
.executeUpdate();
出现同样的错误:
Template is not mapped [update Template t set t.used = true WHERE t.applicationProcess.id=:apId]
有什么想法吗?
更新
我通过创建本机查询来修复它
int v = entityManager.createNativeQuery("update ApplicationProcess_defaultTemplates t set t.used=true where t.ApplicationProcess_id=:apId").setParameter("apId", ap.getId()).executeUpdate();
答案 0 :(得分:2)
在hql中你不想做什么:因为嵌入式对象不是实体,所以它们不能出现在hql查询的from子句中。要更新该对象,您需要将它放在from子句中。
所以你有两种可能性:
答案 1 :(得分:0)
我认为你不能。 Hibernate只允许更新实体,而不是嵌入式或映射的超类。要获取模板,您需要加入,但在HQL更新中不允许加入。以下是HQL docs:
的相关限制没有隐式或显式的连接, 可以在批量HQL查询中指定。 可以在子查询中使用子查询 where子句,子查询所在的位置 它们本身可能包含连接。
您将不得不使用本机SQL或检索并更改java代码中的字段值。
答案 2 :(得分:0)
嵌入式无法直接查询(批量与否),它们不是独立的对象,因为它们没有Id
(并且设置backref到拥有类将无法实现)。
通过EntityManager
更新拥有对象,或者将Template
设为实体。