有没有办法在hibernate中有选择地将记录加载到一个惰性集合中?

时间:2015-07-24 18:16:51

标签: java sql hibernate

我想知道是否可以在hibernate中返回持久化实体列表,并且只将选定记录加载到该列表中每个实体的集合中。例如,我有一个大约5000个股票代码的列表,每个股票代码都有一组价格记录。所以我不想将所有价格记录添加到每个代码中,也许最后350个左右。我不确定如何做到这一点,但我的所有尝试都提出了ClassCastExceptions或Query错误。

这是我的Ticker课程/配置:

@Entity
@Table(name="tickers",
            uniqueConstraints =
            @UniqueConstraint(columnNames={"symbol"}))
@SecondaryTable(name="groups")
public class Ticker implements Persistable{

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ticker_id", nullable=false, unique=true, length=11)
@Type(type="integer")
public int getTickerId() {
    return this.tickerId;
}
public void setTickerId(int tickerId) {
    this.tickerId = tickerId;
}
private int tickerId;


@Column(name="name", nullable=false, unique=false, length=60)
@Type(type="java.lang.String")
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
private String name;


@Column(name="symbol", nullable=false, unique=true, length=10)
@Type(type="java.lang.String")
@NaturalId
public String getSymbol() {
    return symbol;
}
public void setSymbol(String symbol) {
    this.symbol = symbol;
}
private String symbol;


@Column(name="type", nullable=false, unique=false, length=20)
@Enumerated(value=EnumType.STRING)
public TickerType getTickerType() {
    return tickerType;
}
public void setTickerType(TickerType tickerType) {
    this.tickerType = tickerType;
}
private TickerType tickerType;


@Column(name="supergroup", nullable=true, unique=false, length=100, table="groups")
@Enumerated(value=EnumType.STRING)
public TickerSuperGroup getTickerSuperGroup() {
    return tickerSuperGroup;
}
public void setTickerSuperGroup(TickerSuperGroup tickerSuperGroup) {
    this.tickerSuperGroup = tickerSuperGroup;
}
private TickerSuperGroup tickerSuperGroup;


@Column(name="industrygroup", nullable=true, unique=false, length=100, table="groups")
@Enumerated(value=EnumType.STRING)
public TickerGroup getTickerGroup() {
    return tickerGroup;
}
public void setTickerGroup(TickerGroup tickerGroup) {
    this.tickerGroup = tickerGroup;
}
private TickerGroup tickerGroup;


@Column(name="subgroup", nullable=true, unique=false, length=100, table="groups")
@Enumerated(value=EnumType.STRING)
public TickerSubGroup getTickerSubGroup() {
    return tickerSubGroup;
}
public void setTickerSubGroup(TickerSubGroup tickerSubGroup) {
    this.tickerSubGroup = tickerSubGroup;
}
private TickerSubGroup tickerSubGroup;


@OneToMany(mappedBy="ticker", targetEntity=com.lisria.model.historical.PriceRecord.class,
        cascade=CascadeType.ALL, orphanRemoval=true, fetch=FetchType.LAZY)
@OrderBy("trade_date")
private List<PriceRecord> getPriceRecords() {
    return priceRecords;
}
@SuppressWarnings("unused")
private void setPriceRecords(List<PriceRecord> priceRecords) {
    this.priceRecords = priceRecords;
}
private List<PriceRecord> priceRecords = new ArrayList<PriceRecord>();

然后返回一个Tickers列表的方法......

@Override
public List<Ticker> getListOfTickers(Date startDate) {
    Session session = sessionFactory.openSession();
    session.beginTransaction();
@SuppressWarnings("unchecked")
    List<Ticker> tickers = 
        session.createQuery("from Ticker as tickers "
            + "left join tickers.priceRecords as prices "
            + "with prices.tradeDate >=" + startDate.toString()).list();
session.getTransaction().commit();
session.close();
return tickers;
}

getListOfTickers(Date startDate)方法在引用列表中的对象时抛出ClassCastException,因为查询不返回Ticker对象列表。当然,获取代码的简单方法是:

session.createQuery("from Ticker").list()

但这会导致LazyInitialization错误,同时将FetchType更改为eager,甚至初始化集合会导致加载WHOLE集合,这正是我想要避免的。所以,我应该如何处理这个问题,即使我无法获得一个代码列表来迭代,我可以得到一个主键列表,用于加载表中的每个自动收报机,但仍然不知道如何只加载PriceRecords的一部分。

1 个答案:

答案 0 :(得分:1)

所以答案就在这里:

Strategy to fetch a subset of a collection

虽然在搜索引擎中很难找到它,并且它将我的课程与hibernate实现结合起来 - 但我现在仍然忍受它。还有其他答案让我感兴趣。