如何将动态 SQL 列映射到 Hibernate 实体对象?

How to map dynamic SQL column to Hibernate Entity object?

我正在使用具有 4 列的实体 class,因此我的数据库也只有 4 列。但是在编写我的 HQL 时,我正在使用生成 5 列的自定义 SQL 查询。距离场是动态生成的。

@Entity
public class Entity {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;
    private String name;
    private String latitude;
    private String longitude;
    @Transient
    private double distance;
}

现在执行例如查询,如下 -

String q= "Select id, name, latitude, longitude, (latitude - 1) as distance from Entity";
        SQLQuery query = s.createSQLQuery(q);
        query.addEntity(Entity.class);
        List<Entity> results = query.list();

所有其他列都映射到实体对象,但我的距离字段未映射。我将距离注释为瞬态,因为我不想在我的数据库中使用该列,但由于字段是瞬态的,它在 HQL 实体对象中也被忽略了。 请帮我解决一下这个。如何做到这一点?

有两种可能的解决方案。在您的情况下,最好使用 @Formula annotation 声明计算字段。使用此注释,您可以指定 SQL 片段而不是将 属性 映射到列:

@Entity
public class Entity {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;
    private String name;
    private String latitude;
    private String longitude;

    @Formula(latitude - 1)
    private double distance;
}

现在您可以使用顺序正常的HQL 请求获取实体,并计算字段。但请注意,此解决方案仅在您使用 HQL 时有效,但在 JPA 中无效,因为 JPA 不支持 @Formula.

在 JPA 中最好使用 @PostLoad annotation:

@Entity
public class Entity {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;
    private String name;
    private String latitude;
    private String longitude;

    @Transient
    private double distance;

    @PostLoad 
    public void postLoad(){
        distance = latitude - 1;
    }
}

然后你可以用普通的 JPQL 获取这个实体。