有没有人知道如何通过@PersistenceUnit注释通过构造函数设置EntityManagerFactory。我可以通过xml配置。但我不知道相应的注释配置。
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml" />
<property name="persistenceUnitName" value="myUnit"></property>
<bean id="handler" class="com.handler.LocalHTHandler">
<constructor-arg ref="entityManagerFactory"></constructor-arg>
它工作正常。我们可以通过我的处理程序bean的注释来完成它。我听说过@persistanceunit,但它不能放在构造函数中来实现它。那是对的吗?
答案 0 :(得分:2)
Spring不能使用JSR 330注释。目前,由于packaging
被定义为不允许参数,因此无法将EntityManage注入构造函数中。见https://java.net/jira/browse/JPA_SPEC-72
答案 1 :(得分:1)
在我们的代码中,我们有一个base dao对象,它通过PersistenceContext使用注入的实体管理器:
public abstract class BasicJpaDao<T> implements IBasicDao<T> {
@PersistenceContext(type = PersistenceContextType.TRANSACTION, unitName = "default")
protected EntityManager entityManager;
// Default constructor for Spring
public BasicJpaDao() {}
//Use this constructor to set the entity manager yourself
public BasicJpaDao(EntityManager entityManager) {
this.entityManager = entityManager;
}
...
}
持久性单元在应用程序上下文文件中定义如下:
<!-- JPA -->
<!-- Creates an EntityManagerFactory for use with the Hibernate JPA provider -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSourceGlobal" />
<property name="packagesToScan" value="me.comocomo.nutrino.domain.jpa" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="jpaPropertyMap">
<map merge="true">
<entry key="hibernate.format_sql" value="${hibernate.format_sql}" />
</map>
</property>
</bean>
<!-- jpaVendorAdapter (works in conjunction with the persistence.xml) -->
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="${jpa.database}" />
<property name="showSql" value="${jpa.showSql}" />
<property name="databasePlatform" value="${jpa.dialect}" />
<property name="generateDdl" value="${jpa.generateDdl}" />
</bean>
<!-- In order to enable EntityManager injection -->
<bean id="persistenceAnnotation"
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<!-- Transactions -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSourceGlobal" />
</bean>
类似地,您可以创建一个EntityManagerFactoryFactory类,它使用Injection获取EntityManagerFactory,然后将工厂传递给您的bean:
@Component
public class EntityManagerFactoryFactory {
@Inject
private EntityManagerFactory factory;
}
答案 2 :(得分:1)
正如@Dherik所说,您可以通过构造函数来实现。下面的多数据源示例(在SpringBoot 2.0.4上测试):
SomeRepository.java
@Repository
public class SomeRepository {
private final EntityManager entityManager;
public TestService(@Qualifier("someEntityManagerFactory") EntityManager entityManager) {
this.entityManager = entityManager;
}
}
SomeDatabaseConfig.java
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.orm.jpa.vendor.HibernateJpaDialect;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "someEntityManagerFactory")
@EnableConfigurationProperties(JpaProperties.class)
class SomeDatabaseConfig {
private static final String PERSISTENCE_UNIT = "some";
private static final String[] PACKAGES_TO_SCAN = {"package.where.you.store.your.entities"};
@Bean(name = "someDataSourceProps")
@ConfigurationProperties("some.datasource")
DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
@Bean(name = "someDataSource")
DataSource dataSource(@Qualifier("someDataSourceProps") DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
@Bean(name = "someEntityManagerFactory")
LocalContainerEntityManagerFactoryBean entityManagerFactory(
JpaProperties jpaProperties,
@Qualifier("someDataSource") DataSource dataSource,
@Qualifier("someJpaVendorAdapter") JpaVendorAdapter jpaVendorAdapter) {
return createEntityManagerFactory(jpaProperties, dataSource, jpaVendorAdapter, PERSISTENCE_UNIT, PACKAGES_TO_SCAN);
}
@Bean("someJpaVendorAdapter")
JpaVendorAdapter jpaVendorAdapter(JpaProperties jpaProperties) {
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setShowSql(jpaProperties.isShowSql());
return vendorAdapter;
}
@Bean(name = "someTransactionManager")
PlatformTransactionManager transactionManager(@Qualifier("someEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
static LocalContainerEntityManagerFactoryBean createEntityManagerFactory(JpaProperties jpaProperties, DataSource dataSource, JpaVendorAdapter jpaVendorAdapter, String persistenceUnit, String[] packagesToScan) {
final LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
factoryBean.setJpaDialect(new HibernateJpaDialect());
factoryBean.setJpaPropertyMap(getVendorProperties(jpaProperties));
factoryBean.setPersistenceUnitName(persistenceUnit);
factoryBean.setPackagesToScan(packagesToScan);
return factoryBean;
}
private static Map<String, Object> getVendorProperties(JpaProperties jpaProperties) {
return jpaProperties.getHibernateProperties(new HibernateSettings());
}
}
Application.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
@SpringBootApplication(
exclude = {
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class
}
)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
答案 3 :(得分:0)
Currenctly,Spring team says可以通过构造函数注入EntityManager,因为它们已经在Spring JPA Repository上使用了。
只需:
private final EntityManager em;
public YourRepository(EntityManager em) {
this.em = em;
}
我测试了。工作:)。不再进行现场注射。
答案 4 :(得分:0)
如果您出于某种原因不想在您的项目中使用 Spring Data(例如,您只是将遗留项目做得更好一些),您可以创建以下 FactoryBean
来使 EntityManager
可通过构造函数注入注入:
/**
* Makes the {@link EntityManager} injectable via <i>@Autowired</i>,
* so it can be injected with constructor injection too.
* (<i>@PersistenceContext</i> cannot be used for constructor injection.)
*/
public static class EntityManagerInjectionFactory extends AbstractFactoryBean<EntityManager> {
@PersistenceContext
private EntityManager entityManager;
@Override
public Class<?> getObjectType() {
return EntityManager.class;
}
@Override
protected EntityManager createInstance() {
return entityManager;
}
}
请注意,因为我们在内部使用 @PersistenceContext
注释,返回的 EntityManager
将是一个适当的线程安全代理,因为它会直接在使用字段注入的地方注入.