开发者

How to create custom query for CollectionOfElements

I have problems creating a custom query.

This is what entities:

@Entity
public class ApplicationProcess {

    @CollectionOfElements
    private Set<Template> defaultTemplates;
    //more fields
}

And 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() {
 开发者_C百科}

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

I want to create a update statement. I have tried these two:

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]

And I have tried

 int v = entityManager.createQuery("update Template t set t.used = true " + "WHERE t.applicationProcess.id=:apId").setParameter("apId", ap.getId())
   .executeUpdate();

With the same error:

Template is not mapped [update Template t set t.used = true WHERE t.applicationProcess.id=:apId]

Any ideas?

UPDATE

I fixed it by creating native query

int v = entityManager.createNativeQuery("update ApplicationProcess_defaultTemplates t set t.used=true where t.ApplicationProcess_id=:apId").setParameter("apId", ap.getId()).executeUpdate();


What you want to do is not possible in hql : as embedded objects are not entities, they cannot appear in the from clause of hql queries. And to do an update of that object you need it to be in the from clause.

So you have two possibilities :

  • Either use a sql query (be careful to know the (lack of) impact of sql update on the current session entities)
  • refactor your Template class to an entity


I don't think you can. Hibernate only allows updates on entities, not embeddables or mapped superclasses. To get to Template, you need to join, but joins aren't allows in HQL updates. Here's the relavent restriction from the HQL docs:

No joins, either implicit or explicit, can be specified in a bulk HQL query. Sub-queries can be used in the where-clause, where the subqueries themselves may contain joins.

You've going to have to uses either native SQL or retrieve and change the field values in java code.


Embeddables cannot be queried directly (bulk or not), they are not independent objects as they have no Id (and setting a backref to the owning class won't make it possible).

Either update the owning object through the EntityManager or make your Template an entity.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜