我有一个稍微复杂的实体,如下所示(请注意具有更多字段的超类):
public class Question extends Entry {
@OneToMany(orphanRemoval = true, mappedBy = "question")
@JsonManagedReference
private List<Answer> answers = new ArrayList<>();
private Long viewCount = 0L;
private Category category;
@OneToMany(mappedBy = "question", fetch = FetchType.LAZY,
cascade = CascadeType.ALL, orphanRemoval = true)
private List<QuestionTranslation> translations = new ArrayList<>();
@Transient
private double distance;
}
从本地查询中检索结果集时,应从数据库计算 distance
。
例如
SELECT q.*, ST_Distance_Sphere(cast(q.location as geometry), ST_MakePoint(cast(?1 as double precision), cast(?2 as double precision))) as distance from question q
由于查询必须使用参数,因此我无法使用@Formula
来注释字段distance
。
我如何将SQL查询结果中的字段distance
映射到我的实体字段distance
,同时让其他所有映射都由Hibernate完成?
基于@gmotux的建议,我创建了一个包装器实体。
@Entity
@SqlResultSetMapping(
name="MappingQ",
entities={
@EntityResult(
entityClass = QuestionWithDistance.class,
fields={
@FieldResult(name="distance",column="distance"),
@FieldResult(name="question",column="question")})})
public class QuestionWithDistance{
@Id
@GeneratedValue
private String id;
@OneToOne
private Question question;
private double distance;
}
查询
Query query = entityManager.createNativeQuery("SELECT q.*, 222.22 as distance from question q", "MappingQ");
但是它总是失败
org.postgresql.util.PSQLException: The column name id1_15_0_ was not found in this ResultSet.
答案 0 :(得分:0)
由于需要额外的参数来计算字段,因此您实际上不能使用@Formula,甚至不能使用getter来计算字段。 不幸的是,对于您的情况,假设您正在为Hibernate使用基于EntityManager的配置,那么想到的唯一一件事就是利用其@PostLoad事件监听器,您可以将其用于在实体加载时计算字段值,例如:
public class Question extends Entry {
@PostLoad
private void postLoad() {
this.distance = DistanceCalculator.calculateDistance(Double param1,Double param2);
//other calculations
}
}
这当然只是一种解决方法,这意味着您必须在执行本机查询的某处具有静态方法。 如果可能,我建议从您的Question实体中分离“距离”概念,并在需要时使用本机SQL函数调用或服务方法进行计算。