English 中文(简体)
Hibernate query with fetch question
原标题:
  • 时间:2009-11-13 15:50:16
  •  标签:
  • hibernate

I have a 2 entities in a One-To-Many relationship:

OfficeView.java:

public class OfficeView implements java.io.Serializable {

    private Integer officeId;
    private String addr1;
    private String city;
    private String state;
    private String zip;
    private List<Devices> devices;

getters and setters

    @OneToMany(mappedBy = "officeView", fetch = FetchType.EAGER)
    public List<Devices> getDevices() {
        return devices;
    }

    public void setDevices(List<Devices> devices) {
        this.devices = devices;
    }

}

Devices.java:

public class Devices implements java.io.Serializable {

    private Integer devId;
    private String devName;
    private Date lastUpdate;
    private OfficeView officeView;

getters and setters

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "office_id")
    public OfficeView getOfficeView() {
        return officeView;
    }

    public void setOfficeView(OfficeView officeView) {
        this.officeView = officeView;
    }

}

For some devices, in the table there are 2 almost identical entries except for lastUpdate. I always want to retrieve the most recent entry in the table. And only that entry.

For example you have 2 entries for this device:

SSA-PITTSB-PA-NEF82 2009-10-12 23:51:07 SSA-PITTSB-PA-NEF82 2009-10-15 14:19:35

When I load the OfficeView instance for the office containing this (and other devices) I only want to fetch the most recent of these 2 devices. In the database, I can get that short list from the devices table with this SQL query:

select t.* from
  (select dev_id, dev_name, max(last_update) maxValue 
from devices
  group by dev_name) x
join devices t on x.dev_name=t.dev_name
and x.maxValue=t.last_update

SSA-PITTSB-PA-NEF82 2009-10-15 14:19:35

This is a seam application and OfficeViewHome.java, from which the query is called, extends EntityHome. I think the correct way to do this is to overload loadInstance with a customized query.

I just have no idea how to construct the query. How do I do this?

I know how to write the join query in SQL to join the oFfice_view and devices tables and get all the correct data. But I can t use this query to load the instance (as in createNativeQuery) because the data from the devices table needs to be loaded as a list of Devices objects.

I really hope this makes sense because I am utterly stumped.

april26

最佳回答

You ll have to override collection loader - be aware that this is a Hibernate extension to JPA standard. You can use an SQL query to do this instead of writing HQL - indeed, writing HQL may be somewhat troublesome in this scenario.

@Loader(namedQuery = "latestDevices")
@NamedNativeQuery(name="latestDevices", query="...", resultClass = Devices.class)
@OneToMany(mappedBy = "officeView", fetch = FetchType.EAGER)
public List<Devices> getDevices() {
  return devices;
}

The actual query is the one you wrote above with additional condition on office_id, whose parameter value is going to be supplied by Hibernate:

select t.* from
 (select dev_id, dev_name, max(last_update) maxValue 
    from devices
   group by dev_name) x
  join devices t on x.dev_name=t.dev_name
   and x.maxValue=t.last_update
   and t.office_id = ?

If the names are not unique throughout you ll have to rewrite the above to explicitly join office on id for the inner select because you can t repeat the ? placeholder.

Be very careful with updating / deleting Devices through collection on Office, Hibernate attempts to optimize certain operations and may end up deleting devices for given Office that weren t retrieved by above select.

问题回答

暂无回答




相关问题
Multiple Hibernate instances using C3P0

I am facing a weird problem and it seems to be c3p0 related. I am starting two instances of an app in the same java vm which interact with each other. After some operations "APPARENT DEADLOCK" ...

Hibernate vs Ibatis caching

We can speed up a hibernate app easyly with 2nd level cache using infinispan or ehcache/terracotta,... but ibatis only have a simple interface to implement for caching. And hibernate knows more ...

Using annotations to implement a static join in hibernate

I m relatively new to hibernate and was wondering if someone could help me out. While I have no issues implementing a normal join on multiple columns in hibernate using the @JoinColumns tag, I m ...

Hibernate query with fetch question

I have a 2 entities in a One-To-Many relationship: OfficeView.java: public class OfficeView implements java.io.Serializable { private Integer officeId; private String addr1; private ...

hibernate interceptors : afterTransactionCompletion

I wrote a Hibernate interceptor : public class MyInterceptor extends EmptyInterceptor { private boolean isCanal=false; public boolean onSave(Object entity, Serializable arg1, Object[] arg2, String[]...

How to prevent JPA from rolling back transaction?

Methods invoked: 1. Struts Action 2. Service class method (annotated by @Transactional) 3. Xfire webservice call Everything including struts (DelegatingActionProxy) and transactions is configured ...

Hibernate/GORM: collection was not processed by flush()

I have an integration test in my Grails application that fails when I try to save an entity of type Member invitingMember.save(flush: true) This raises the following exception org.hibernate....

Hibernate Criteria API equivalent for "elements()"

Is it possible to implement the following query using Criteria API? select order from ORDER as order,ITEM as item where item.itemID like ITM_01 and item in elements(order.items)

热门标签