JPA SqlResultSetMapping到属性中有复杂对象的pojo



我想知道是否有可能(如果这是一个好方法)在pojo中映射本地查询的sql结果与其他pojo的属性。我正在搜索这样的内容:

<<p>ResultPojo类/strong>
public class ResultPojo {
private MyPojo myPojo;
private Integer firstSimpleAttribute;
private Integer secondSimpleAttribute;
private Double thirdSimpleAttribute;

// Empty Constructor + Constructor with fields + Getter + Setter

}
<<p>MyPojo类/strong>
public class MyPojo {
private Long id;
private String label;
private MySubPojo mySubPojo;

// Empty Constructor + Constructor with fields + Getter + Setter

}
<<p>MySubPojo类/strong>
public class MySubPojo {
private String text;

// Empty Constructor + Constructor with fields + Getter + Setter

}
<<p>映射部分/strong>
@SqlResultSetMapping(
name = "CustomMapping",
classes={
@ConstructorResult(
targetClass=MyPojo.class,
columns={
@ColumnResult(name="id", type=Long.class),
@ColumnResult(name="label", type=String.class),
@ColumnResult(name="mySubPojo", type=MySubPojo.class)
}
)
},
columns = {
@ColumnResult(name = "firstSimpleAttribute", type = Integer.class),
@ColumnResult(name = "secondSimpleAttribute", type = Integer.class),
@ColumnResult(name = "thirdSimpleAttribute", type = Double.class)
}
)

原生查询

Query query = this.entityManager.createNativeQuery(
"SELECT r.*, me.id, me.label, mse.*
FROM result r 
INNER JOIN my_entity me ON r.id_my_entity = me.id_my_entity 
INNER JOIN my_sub_entity mse ON me.id_my_sub_entity = mse.id_my_sub_entity",
"CustomMapping");
List<Object[]> result = query.getResultList();
// Convert Object[] to List<ResultPojo>

当我这样做时,我得到了NullPointerException由于行@ColumnResult(name="mySubPojo", type=MySubPojo.class)。是否有一种方法来管理这种映射?

您需要使用@TypeDef和POJO实现UserType- POJO作为自定义类型https://www.baeldung.com/hibernate-custom-types

Likeclass MySubPojo implements UserType

你不能这么做除了UserType方法,但是,这种形式在Hibernate 6.0和真的很麻烦使用这个特定的用例。我建议您将列单独映射到基本类型的构造函数参数,并在构造函数中构造您需要的任何类型。

如果你可以避免本地查询,你可以使用Blaze-Persistence实体视图,我认为它非常适合你的需要。

我创建的库允许JPA模型和自定义接口或抽象类定义模型之间的轻松映射,类似于类固醇上的Spring Data projection。其思想是,您以您喜欢的方式定义您的目标结构(域模型),并通过JPQL表达式将属性(getter)映射到实体模型。

您的用例的DTO模型可以像下面这样使用Blaze-Persistence Entity-Views:

@EntityView(Entity1.class)
public interface ResultPojo {
@IdMapping
Long getId();
Integer getFirstSimpleAttribute();
Integer getSecondSimpleAttribute();
Double getThirdSimpleAttribute();
@Mapping("myAssociation")
MyPojo getMyPojo();
@EntityView(Entity2.class)
interface MyPojo {
@IdMapping
Long getId();
String getLabel();
@Mapping("subAssociation")
MySubPojo getMySubPojo();
}
@EntityView(Entity3.class)
interface MySubPojo {
String getName();
}
}

假设实体模型类似于以下内容:

@Entity
public class Entity1 {
@Id
Long id;
Integer firstSimpleAttribute;
Integer secondSimpleAttribute;
Double thirdSimpleAttribute;
@ManyToOne(fetch = LAZY)
Entity2 myAssociation;
}
@Entity
public class Entity2 {
@Id
Long id;
String label;
@ManyToOne(fetch = LAZY)
Entity3 subAssociation;
}
@Entity
public class Entity3 {
@Id
Long id;
String label;
}

查询是将实体视图应用于查询的问题,最简单的就是通过id进行查询。

ResultPojo a = entityViewManager.find(entityManager, ResultPojo.class, id);

Spring Data集成允许您几乎像Spring Data projection一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

Page<ResultPojo> findAll(Pageable pageable);

最好的部分是,它只会获取实际需要的状态!

最新更新