给定下面的实体模型:
@Entity(name = "Accounts")
open class AccountEntity(
@field:Id
@field:GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "accounts_sequence_generator")
@field:SequenceGenerator(name = "accounts_sequence_generator", sequenceName = "sequence_accounts")
@field:Column(name = "id", nullable = false, unique = true)
open var id: Long? = null,
@field:[NotBlank Size(min = 2, max = 255, message = "username must be between 2 and 255 characters long")]
@field:Column(name = "username", nullable = false, unique = true)
open var username: String,
@field:Embedded
open var address: Address?
)
@Embeddable
data class Address(
@field:Embedded
val geolocation: Geolocation
)
@Embeddable
data class Geolocation(
@field:Column(name = "geolocation", columnDefinition = "geography(POINT,4326)")
val geolocation: Point
)
我想使用带有构造函数表达式的DTO投影执行查询:
val query = entityManager.createQuery(
"select new org.example.dto.AccountSummary(acc.address.geolocation.geolocation, acc.id, acc.username) from Accounts acc" +
"",
AccountSummary::class.java
)
return query.resultList
其中Account摘要类如下所示:
@Introspected
data class AccountSummary(
val point: Location,
val id: Long,
val username: String
)
但是,我还想对地理位置属性(类型Point)执行类型转换为自定义位置数据类,因此我已注册了从几何到位置的自定义TypeConverter:
@Singleton
class GeometryLocationConverter : TypeConverter<Geometry, Location> {
override fun convert(`object`: Geometry?, targetType: Class<Location>?, context: ConversionContext?): Optional<Location> {
return when (`object`) {
is Point -> Optional.of(Location(`object`.y, `object`.x))
else -> throw Exception("unknown geometry type")
}
}
}
但是,会引发一个异常并出现错误:无法在类Ac扩摘要上找到适当的构造函数。这样的事情可能吗?我没有找到任何展示此用例的示例。
不确定Micronaut是否能够做到这一点,但Blaze-Per持久性实体视图具有类型转换器,并且还可以更轻松地编写查询。
我创建了这个库,以允许JPA模型和自定义接口或抽象类定义模型之间的轻松映射,类似于类固醇上的Spring数据投影。这个想法是您按照自己喜欢的方式定义目标结构(领域模型),并通过JPQL表达式将属性(getter)映射到实体模型。
您的用例的DTO模型可能与Blaze-Per的Entity-Views类似:
@EntityView(AccountEntity.class)
public interface AccountSummary {
@IdMapping
Long getId();
String getUsername();
@Mapping("address.geolocation.geolocation")
Location getLocation();
}
查询是将实体视图应用于查询的问题,最简单的是通过id进行查询。
帐户摘要a=entityViewManager. find(entityManager,Account摘要.class,id);
最棒的是,它只会获取实际需要的状态!