我正在为Spring Data JPA存储库编写自定义实现。所以我有:
MyEntityRepositoryCustom
=>界面与自定义方法MyEntityRepositoryUmpl
=>实现上述接口MyEntityRepository
=>扩展JpaRepository
和MyEntityRepositoryCustom
我的问题是:在MyEntityRepositoryUmpl
的实现中,我需要访问注入Spring Data的实体管理器。怎么弄?
我可以使用@PersistenceContext
使其自动装配,但问题是此存储库必须在设置多个持久性单元的应用程序中工作。所以,要告诉Spring我需要哪一个,我必须使用@PersistenceContext(unitName="myUnit")
。但是,由于我的存储库是在可重用的服务层中定义的,因此我无法知道更高级别的应用程序层将配置为注入我的存储库的持久性单元的名称。
换句话说,我需要做的是访问Spring Data本身正在使用的实体管理器,但是在查看Spring Data JPA文档(不那么快)之后我找不到任何东西。< / p>
老实说,Impl
类完全没有意识到Spring Data,虽然在Spring Data手册中被描述为一个优势,但实际上每当你需要访问通常由Spring Data本身提供的东西时都是一个复杂的事实。在你的自定义实现中(几乎总是,我会说......)。
答案 0 :(得分:21)
从Spring Data JPA 1.9.2版本开始,您可以通过JpaContext访问EntityManager,请参阅:http://docs.spring.io/spring-data/jpa/docs/1.9.2.RELEASE/reference/html/#jpa.misc.jpa-context。 例如:
@Component
public class RepositoryUtil
{
@Autowired
private JpaContext jpaContext;
public void deatach(T entity)
{
jpaContext.getEntityManagerByManagedType(entity.getClass()).detach(entity);
}
}
P.S。 如果某个类有多个EntityManager候选,则此方法将无效,请参阅JpaContext#getEntityManagerByManagedType - &gt;的实现。 DefaultJpaContext#getEntityManagerByManagedType。
答案 1 :(得分:4)
我能找到的最好的是建立一个“约定”:我的存储库声明他们希望一个名为myConventionalPU
的持久性单元可用。然后,应用程序层将该别名分配给它设置并注入Spring Data的实体管理器工厂,因此我的自定义实现可以使用该别名通过自动装配接收正确的EMF。以下是我的应用程序上下文的摘录:
<bean id="myEntityManagerFactory" name="myConventionalPU"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
[...]
</bean>
<jpa:repositories base-package="com.example"
entity-manager-factory-ref="myEntityManagerFactory"
transaction-manager-ref="transactionManager" />
在我的自定义实现中:
@PersistenceContext(unitName = "myConventionalPU")
private EntityManager em;
我根据此要求打开了DATAJPA-669。
答案 2 :(得分:3)
Spring Data JPA使用Auto配置类自动生成entityManagerFactory,dataSource和transactionManager。
如果要访问entityManager并控制实例化和设置,则需要定义自己的PersistenceConfiguration。以下是使用Java Config
的示例代码 @Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = { "com.test.repositories.*" })
public class PersistenceJpaConfig {
@Autowired
JpaVendorAdapter jpaVendorAdapter;
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setName("testdb")
.setType(EmbeddedDatabaseType.HSQL)
.build();
}
@Bean
public EntityManager entityManager() {
return entityManagerFactory().createEntityManager();
}
@Bean
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
lef.setDataSource(dataSource());
lef.setJpaVendorAdapter(jpaVendorAdapter);
lef.setPackagesToScan("com.test.domain.*");
lef.afterPropertiesSet();
return lef.getObject();
}
@Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager(entityManagerFactory());
}
}
如果您有多个数据源,follow this article.