Jpa + Spring - 从数据库读取后自动设置瞬态字段值

Posted

技术标签:

【中文标题】Jpa + Spring - 从数据库读取后自动设置瞬态字段值【英文标题】:Jpa + Spring - automatically setting transient field value after read from DB 【发布时间】:2013-09-03 10:05:51 【问题描述】:

在从数据源读取实体后,为标记为 @Transient 的字段设置值的最佳解决方案是什么?

我正在使用 EclipseLink,并且我正在尝试 DescriptorEventAdapter 和他的 postBuild 事件解决方案,因为我还需要使用 Spring bean 获取默认值(显然使用 DI),但我会知道是否有任何更简单的解决方案我不见了。

提前致谢

【问题讨论】:

【参考方案1】:

您得到了具有瞬态字段的实体,并且该值始终使用 DI 从服务中获取?

    该字段的用途是什么?它用于任何实体方法中的某些计算? 这样的计算大概应该使用服务的方法来获取值。 由于使用了任何服务的值,我不确定这种计算(方法)是否属于实体。

请注意,实体和服务具有完全不同的生命周期。值是随时间变化的,所以在实体的生命周期之初就在它的工厂中提供值是没有意义的?

【讨论】:

您好,感谢您的关注。我正在开发一个多租户(多模式)应用程序,所以我想在实体中加载一个包含数据库模式的字段,我从那里加载实体数据(我稍后使用,例如在 GUI 中)。 您是否查看过 EclipseLink 对多租户的内置支持(例如 wiki.eclipse.org/EclipseLink/Examples/JPA/Multitenant)? 是的,但是使用多模式的多租户有一个错误,我提交了一个错误,所以我决定以另一种方式进行。【参考方案2】:

如果您使用的是存储库或 DAO,以下是简单的方法:

@Repository
class YourRepository 

    @Autowired
    private Bean bean;

    @PersistenceContext
    private EntityManager entityManager;

    @Transactional(readOnly = true)
    public YourEntity find(..) 
        YourEntity entity = lookupUsingEntityManager();
        entity.transientField = bean.getDefaultValue();
        return entity;
    

如果您使用的是活动记录式实体,这是另一种方法:

@Entity
class YourEntity 

    @Transient
    public Object field;

    @PostLoad
    public void populateField() 
        field = new BeanHolder().bean.getDefaultValueForField();
    

    @Configurable
    private static class BeanHolder 
        @Autowired private Bean bean;
    

注意半伪代码。请注意,仅当您将编译时或加载时 AspectJ 编织与 <context:spring-configured /> 一起使用时,后一种方法才有效。

【讨论】:

您好,感谢您的关注。第一种方法是我刚刚使用的方法,但使用的是 Spring Data JPA(及其预先编写的存储库工具),我不想覆盖所有的 crud 方法(findOne、findAll、save),所以我想只采取行动在实体层面。第二种方法可能没问题,但是没有 AspectJ 编织就没有解决方案(例如使用 EclipseLink 特定的 API)?

以上是关于Jpa + Spring - 从数据库读取后自动设置瞬态字段值的主要内容,如果未能解决你的问题,请参考以下文章

Spring JPA - 与关系一起读取数据 - 性能改进

Spring Boot + Spring Batch + Spring JPA

Spring Boot 不会从 application.properties 为数据库创建自动配置

spring boot jpa 配置了yml文件后怎么扫描包

使用spring数据jpa在存储过程中读取ref游标作为输出参数返回null

多线程jpa读取时休眠空指针异常