views:

157

answers:

3

Hi.

I have problems creating a custom query.

This is what entities:

@Entity
public class ApplicationProcess {

    @CollectionOfElements

private Set 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() { }

@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();
+2  A: 

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
Thierry
A: 

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.

sblundy
A: 

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.

Pascal Thivent