我正在使用Spring 4.3.x和Hibernate 5.2.x.由于hibernate 5 JPA是使用Spring的用户ORM的标准方法,因此我创建了一个使用Hibernate和JPA的配置。
我的弹簧配置是,
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.orm.hibernate5.HibernateExceptionTranslator;
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.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.zaxxer.hikari.HikariDataSource;
@Configuration
@ComponentScan(basePackages = { "com.example.reports" })
@EnableTransactionManagement
@PropertySource(value = { "classpath:application.properties" })
public class SuperUserReportSpringConfiguration {
@Autowired
Environment environment;
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendeorAdapter) {
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
entityManagerFactory.setDataSource(dataSource);
entityManagerFactory.setJpaVendorAdapter(jpaVendeorAdapter);
entityManagerFactory.setPackagesToScan("com.example.reports.domain");
entityManagerFactory.setPersistenceUnitName("onlineDB");
return entityManagerFactory;
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setShowSql(false);
adapter.setDatabasePlatform("org.hibernate.dialect.DB2400Dialect");
return adapter;
}
@Bean
DataSource dataSource() {
HikariDataSource ds = new HikariDataSource();
ds.setPoolName("hikariCP");
ds.setDriverClassName(this.environment.getProperty("jdbc.as400.db2.db.driver.classname"));
ds.setJdbcUrl(this.environment.getProperty("jdbc.as400.db2.db.url"));
ds.setUsername(this.environment.getProperty("jdbc.as400.db2.db.username"));
ds.setPassword(this.environment.getProperty("jdbc.as400.db2.db.password"));
ds.setMaximumPoolSize(10);
return ds;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager(emf);
return transactionManager;
}
@Bean
public HibernateExceptionTranslator hibernateExceptionTranslator() {
return new HibernateExceptionTranslator();
}
}
我尝试使用javax.transaction.Transactional和org.springframework.transaction.annotation.Transactional
中的@Transactional
在这两种情况下,事务管理器都不工作,我在尝试从用户实体获取子元素时遇到错误,
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.reports.domain.User.userInetAddrs, could not initialize proxy - no Session
我不确定我是否缺少任何配置。
Hibernate实体,
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
private Set<UserInetAddr> userInetAddrs = new HashSet<UserInetAddr>(0);
@Transactional
User user = superUserReportDao.getUserSecurityRoles(id);
user.getUserInetAddrs().forEach(inetAddress -> {
});
使用@Transactional
public User getUser(int userSeqId) {
return entityManager.find(User.class, userSeqId);
}
DAO班级交易,
@Repository("superUserReportDao")
@Slf4j
@Transactional
public class SuperUserReportDaoImpl implements SuperUserReportDao {
@PersistenceContext(unitName="onlineDB")
private EntityManager onlineEntityManager;
服务类,
@Service("superUserReportService")
@Slf4j
public class SuperUserReportServiceImpl implements SuperUserReportService {
@Resource(name = "superUserReportDao")
private SuperUserReportDao superUserReportDao;
public void generateSuperUserReport() throws SQLException {
// -- generate Customer Super user report
generateSuperUserEmail(UserType.CUSTOMER);
}
@Transactional
private void generateSuperUserEmail(UserType userType) throws SQLException {
...
我的主要班级,
@Slf4j
@Component
public class SuperUserReportMain {
@Resource(name = "superUserReportService")
SuperUserReportService superUserReportService;
/**
* @param args
* @throws SQLException
*/
public static void main(String[] args) throws SQLException {
ApplicationContext context = new AnnotationConfigApplicationContext(SuperUserReportSpringConfiguration.class);
SuperUserReportMain reportMain = context.getBean(SuperUserReportMain.class);
reportMain.generateSuperUserReport();
((AnnotationConfigApplicationContext)context).close();
}
public void generateSuperUserReport() throws SQLException {
superUserReportService.generateSuperUserReport();
}
}