【问题标题】:JPA Interface extending JpaRepository only, with use of EntityManager in default methods仅扩展 JpaRepository 的 JPA 接口,在默认方法中使用 EntityManager
【发布时间】:2022-02-25 17:45:15
【问题描述】:

首先,对于那些想知道如何在扩展 JpaRepository 的接口中使用 EntityManager 的人。 这是一个潜在的解决方案。 但 !!!我知道这可能是一种 baaaad 做法,Spring 和 JPA 中经验丰富的人可能会试图杀死我;)道歉......

所以,在这个大警告之后,这是我的问题:

我只想使用没有自定义实现的接口,这就是我所做的:

@Repository
@Transactional
public interface BookingDao extends JpaRepository<Booking, Long> {

    Booking findByCodeId(String codeId);

    void deleteByCodeId(String codeId);

    default Integer findCountOfBookingOldDay() {
        EntityManager entityManager = ApplicationContextProvider.getEntityManager();
        Query query = entityManager.createNativeQuery("XXXX");
        Number result = (Number) query.getSingleResult();
        return result.intValue();
    }
}
    @Component(value = "applicationContextProvider")
    public class ApplicationContextProvider implements ApplicationContextAware {
        private static ApplicationContext context;
        public static ApplicationContext getApplicationContext() {
            return context;
        }
        public static EntityManager getEntityManager() {
            return EntityManagerFactoryUtils.getTransactionalEntityManager(context.getBean(LocalContainerEntityManagerFactoryBean.class).getObject());
            return context.getBean(EntityManager.class);
        }
        @Override
        public void setApplicationContext(ApplicationContext ac) throws BeansException {
            context = ac;
        }
}

我知道这可能不是最佳实践,最好的方法是在一个类中使用 @PersistenceContext(注意为每个线程创建一个唯一的 EntityManager)......但是在我的情况下最好的选择:

这个:

return EntityManagerFactoryUtils.getTransactionalEntityManager(context.getBean(LocalContainerEntityManagerFactoryBean.class).getObject());

或者这个:

return context.getBean(EntityManager.class)

或者可能是另一种更好的方法,仍然只使用界面。

感谢您的评论/建议。

PS:“EntityManagerFactoryUtils”和 PersistenceContext 做的不一样?

【问题讨论】:

    标签: java spring spring-data-jpa


    【解决方案1】:

    对于你想做的事情,我会在界面中用@Query("&lt;your native select counting what you need&gt;", native=true)注释一个方法。

    当我需要任何花哨的逻辑时,我通常会创建一个服务,它使用这样的存储库:

    @Service
    @Transactional
    public class MyService {
    
        private final MyRepository repository;
    
        @Autowired
        public MyService (MyRepository repository) {
            this.repository = repository;
        }
    
        public int myMethod(){
            //code using repository
        }
    
    }
    

    【讨论】:

    • 感谢您的回复,我也尝试使用@Query native=true,但在这里我不能......这是从双重中选择的。在选择带有日期和日期的序列名称的动态串联中,JPA 不支持选择中的参数注入,我尝试过...
    • 也许您可以尝试为此目的运行匿名块。 stackoverflow.com/questions/63315403/…
    • 我也试过 :) 在 sql developerper 上使用 BEGIN 和 END,它运行良好。除了我无法从中返回值。在谷歌搜索如何返回值后,我多次阅读,这是不可能的。
    • 例如,我无法从@query native true 中返回任何内容:DECLARE v_holding VARCHAR2(1000); v_holding2 VARCHAR2(1000); BEGIN EXECUTE IMMEDIATE q'[select trim(to_char(sysdate, 'DAY', 'nls_date_language=english'))||'_BOOKING_SEQ.NEXTVAL' from dual]' INTO v_holding; EXECUTE IMMEDIATE 'select ' || v_holding || ' from dual' INTO v_holding2; END; 从我读到的内容中,即使它在 sql developer 中工作也是不可能的
    • 抱歉,我不知道还能尝试什么。
    猜你喜欢
    • 2020-09-01
    • 2013-12-23
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    • 2019-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多