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

4

我正在使用一个实体类,它有4个列,因此我的数据库也只有4个列。但是在编写HQL时,我使用了自定义SQL查询,生成了5个列。距离字段是动态生成的。

@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();

所有其他列都被映射到实体对象,但我的距离字段未被映射。我将距离标注为Transient,因为我不想在数据库中保存该列,但是由于该字段是Transient,它也被忽略了在HQL实体对象中。 请帮我解决这个问题。应该如何处理?


经度和纬度以字符串形式表示。 - Neil Stockton
@neilstockton 哈哈,这只是一个例子问题。这样你也会讨厌类名和公式的:p - Dev Utkarsh
1个回答

2
有两种可能的解决方案。在您的情况下,最好使用 @Formula 注释 声明计算字段。使用此注释,您可以指定 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 注释
@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获取此实体。

正是我想要的。谢谢!你能告诉我在公式或者PostLoad的情况下,如何使用外部参数传递查询吗? - Dev Utkarsh
1
很遗憾,您无法将动态参数传递给 @Formula。但是您可以从 @PostLoad 中读取参数,该参数存储在之前的 Java 变量中。 - Ken Bekov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接