Java Hibernate使用addEntity创建SQLSQL

前端之家收集整理的这篇文章主要介绍了Java Hibernate使用addEntity创建SQLSQL前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要应用与此类似的SQL查询.
SELECT
    id as id,c03 as c03,c34 as c34 
FROM
    (SELECT
        id,c03,c34 
    FROM
        students
    where
        c34 in(
            ?,?,?
        ) 
    order by
        id desc) o 
group by
    c34;

和我的Java代码.

private final void retrieveStudents(){
    final List result = currentSession()
            .createsqlQuery("SELECT id as id,c34 as c34 FROM (SELECT id,c34,c03 FROM students where c34 in(:filters) order by id desc) o group by c34;")
            .setParameterList("filters",Arrays.asList(74,1812))
            .list();
    result.forEach(this::consumer1);
}

这个查询是OK.返回一个可以迭代的objets数组,但是我想返回一个Student对象,所以我添加.

.addEntity(Student.class)

但是说错了

Column 'ACTIVE' not found.

我也尝试用.addScalar但同样的事情发生.

.addScalar("id",org.hibernate.type.IntegerType.INSTANCE)
.addScalar("c03",org.hibernate.type.DateType.INSTANCE)

哪个是学生的一列,但不是投影我的问题我该怎么做,我只是认为,以某种方式应用别名Hibernate填充学生实体.

所有我想要的是一个学生对象,id,c34值填充.

我做错什么是可能的?

解决方法

对于这种用例,您不希望hibernate将Student视为实体,而是作为DTO.

为此,不要使用addEntity方法,而是setResultTransfomer:

final List result = currentSession()
        .createsqlQuery("SELECT id as id,c34 as c34 " + 
                         "FROM (SELECT id,c03 FROM students " + 
                               "where c34 in(:filters) " + 
                               "order by id desc) o group by c34")
        .setParameterList("filters",1812))
        .addScalar("id",org.hibernate.type.IntegerType.INSTANCE)
        .addScalar("c03",org.hibernate.type.DateType.INSTANCE)
        .addScalar("c34",org.hibernate.type.DateType.INSTANCE)
        .setResultTransformer(Transformers.aliasToBean(Student.class))
        .list();

这对于非实体类是有效的,只要类具有与投影列的名称相匹配的setter,并且有一个无参数构造函数.我从来没有在实体类上测试过这个.

如果您没有setter,而是这3个字段的构造函数,可以使用:

// choose here the right constructor
java.lang.reflect.Constructor constructor = Student.class.getConstructors()...
// ...
.setResultTransformer(new AliasToBeanConstructorResultTransformer(constructor));

代替.

编辑:
我不会使用一个实体作为一个DTO(但是为这个用例创建一个特定的DTO):如果你的一个服务认为实体被加载了一个正常的方式(所以被完全初始化),做一些修改(更新一个字段为例),并保存实体?

在最好的情况下,不可空字段(在db端)将不会被初始化,您将收到一个ConstraintViolationException并触发回滚,从而保持数据的安全.

在最坏的情况下,您将通过将实体的所有字段设置为null,而将三个已加载的字段设置为null来破坏数据.

原文链接:https://www.f2er.com/java/123111.html

猜你在找的Java相关文章