hibernate 微自动投影DTO类型转换

jljoyd4f  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(157)

给定以下实体模型:

@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

其中,AccountSummary 类如下所示:

@Introspected
data class AccountSummary(
    val point: Location,
    val id: Long,
    val username: String
)

但是,我还想将geolocation属性(类型为 Point)转换为自定义的 Location 数据类,因此我注册了一个从 GeometryLocation 的自定义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")
        }
    }
}

但是,会掷回例外状况,错误如下:无法在类AccountSummary上找到适当的构造函数。是否可能发生类似的情况?我尚未找到任何展示此用例的示例。

dffbzjpn

dffbzjpn1#

不确定Micronaut是否能够做到这一点,但Blaze-Persistence实体视图有类型转换器,也将使编写查询更容易。
我创建这个库是为了允许在JPA模型和自定义接口或抽象类定义的模型之间进行简单的Map,就像Spring Data Projections一样。其思想是,您可以按照自己喜欢的方式定义目标结构(域模型),并通过JPQL表达式将属性(getter)Map到实体模型。
使用Blaze-Persistence Entity-Views时,您的用例的DTO模型可能如下所示:

@EntityView(AccountEntity.class)
public interface AccountSummary {
    @IdMapping
    Long getId();
    String getUsername();
    @Mapping("address.geolocation.geolocation")
    Location getLocation();
}

查询是将实体视图应用于查询的问题,最简单的是按id查询。
AccountSummary a = entityViewManager.find(entityManager, AccountSummary.class, id);
最好的部分是,它只会获取实际需要的状态!

相关问题