hibernate criteria.setResultTransformer()with projections.distinct(复合外键)

时间:2012-02-15 18:16:37

标签: hibernate distinct

我有SQL:

SELECT DISTINCT archiveSer, clas, classifdegree
FROM realization_archive
WHERE realId = 2
ORDER BY archiveSer DESC

我的表在hibernate中映射如下:

主表(realization_archive):

public class RealizationArchive implements Serializable {
@Id
@Access(AccessType.PROPERTY)
@Column(name = "archiveSer", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long archiveSerial;

@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY)
@JoinColumn(name = "realId", referencedColumnName = "realId", nullable = false)
private CreditRealization creditRealization;

@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY, optional = true)
@JoinColumns({ @JoinColumn(name = "classif", referencedColumnName = "classif"), @JoinColumn(name = "classifdegree", referencedColumnName = "classifdegree") })
private ClassificationDegree classification;

...
}

主表RealizationArchive(realization_archive)中的复合外键对象

public class ClassificationDegree implements Serializable{
@Id
@Access(AccessType.PROPERTY)
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;

@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "classif", referencedColumnName = "clas", nullable = false)
private ClassificationLevel classificationLevel;

@Column(name = "classifdegree")
private Integer classificationDegree;
...
}
ClassificationDegeree中的简单foregin键

public class ClassificationLevel implements Serializable {
@Id
@Access(AccessType.PROPERTY)
@Column(name = "clas", nullable = false)
private Integer classificationLevelId;

...
}

RealizationArchive中的简单外键

public class CreditRealization implements Serializable{
@Id
@Access(AccessType.PROPERTY)
@Column(name = "realId", nullable = false)
private Long creditRealizationId;
...
}

我正在尝试使用以下标准执行之前提到的SQL查询:

Criteria criteria = getSession().createCriteria(RealizationArchive.class);
        criteria.add(Restrictions.eq("creditRealization.creditRealizationId", creditRealizationId));
        criteria.addOrder(Order.desc("archiveSerial"));
        criteria.setProjection(Projections.distinct(Projections.projectionList().add(Projections.property("creditRealization").as("creditRealization"))
                .add(Projections.property("archiveSerial").as("archiveSerial"))
                .add(Projections.property("classification").as("classification"))));
        criteria.setMaxResults(1);

        criteria.setResultTransformer(Transformers.aliasToBean(RealizationArchive.class));
        return criteria.uniqueResult();
}

但是,我的问题是在返回的对象(RealizationArchive)中为字段值     RealizationArchive.classification.classificationDegree 和     RealizationArchive.classification.classificationLevel.classificationLevelId 没有正确加载。 (它们具有空值,但在数据库中它们是例如0,1)。 它适用于简单的外键(例如,用于creditRealization [realId]),但是当我有复合外键(例如用于分类[classif,classifdegree])时,不会加载值...底线,我的SQL查询生成得很好(语法上) ),但返回对象的所有值都设置为corectlly,除了那些属于复合外键的那个(即classificationLevelId(db name-clas)和classificationDegree(db name-clasifdegree))...

这可以通过标准来完成,如果是这样,怎么做?我不明白,我做错了什么? 任何形式的帮助都表示赞赏,提前感谢您的时间和耐心:)

mismas

1 个答案:

答案 0 :(得分:0)

为什么要使用投影,因为您要加载的是实体实例?为什么要使用Criteria进行这样的查询,这不需要动态组合。

这是相应的HQL:

select r from RealizationArchive r 
where r.creditRealization.creditRealizationId = :creditRealizationId 
order by r.archiveSerial desc

如果你真的想让自己的生活变得困难,并且使用这个标准,你只需要这个:

Criteria c = session.createCriteria(RealizationArchive.class, "r");
c.add(Restrictions.eq("r.creditRealization.creditRealizationId", creditRealizationId);
c.addOrder(Order.desc("r.archiveSerial"))

如果您刚刚为ID属性id命名,那么您的代码将更具可读性和简洁性。命名CreditRealization creditRealizationId的ID是多余的。