如何为CollectionOfElements创建自定义查询

时间:2010-06-18 12:23:41

标签: java hibernate orm jpa

我在创建自定义查询时遇到问题。

这就是实体:

@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();

3 个答案:

答案 0 :(得分:2)

在hql中你不想做什么:因为嵌入式对象不是实体,所以它们不能出现在hql查询的from子句中。要更新该对象,您需要将它放在from子句中。

所以你有两种可能性:

  • 使用sql查询(小心了解sql update对当前会话实体的影响(缺乏))
  • 将您的Template类重构为实体

答案 1 :(得分:0)

我认为你不能。 Hibernate只允许更新实体,而不是嵌入式或映射的超类。要获取模板,您需要加入,但在HQL更新中不允许加入。以下是HQL docs

的相关限制
  

没有隐式或显式的连接,   可以在批量HQL查询中指定。   可以在子查询中使用子查询   where子句,子查询所在的位置   它们本身可能包含连接。

您将不得不使用本机SQL或检索并更改java代码中的字段值。

答案 2 :(得分:0)

嵌入式无法直接查询(批量与否),它们不是独立的对象,因为它们没有Id(并且设置backref到拥有类将无法实现)。

通过EntityManager更新拥有对象,或者将Template设为实体。