i am using H2 in memory database for testing and my configuration is as
follows:
*1- SpringTestingConfig:*
@Configuration
@ComponentScan(basePackages = "com.myapp.data", excludeFilters = {
@Filter(Configuration.class) })
@PropertySource("classpath:/test.properties")
@Profile("test")
public class SpringTestingConfig {
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new
DriverManagerDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl("jdbc:h2:mem:test;MODE=Mysql;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;INIT=CREATE
SCHEMA IF NOT EXISTS MYAPP");
dataSource.setUsername("sa");
dataSource.setPassword("");
return dataSource;
}
}
*2- MyTestClass:*
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({ WebContextTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class })
@ActiveProfiles("test")
@DirtiesContext
@ContextConfiguration(loader = AnnotationConfigContextLoader.class,
classes = {
SpringConfig.class, SpringTestingConfig.class,
SpringLocalContainerJPAConfig.class, CustomConfiguration.class })
@PrepareForTest({ FacesContext.class })
@PowerMockIgnore({ "javax.management.*", "javax.xml.parsers.*",
"com.sun.org.apache.xerces.internal.jaxp.*", "ch.qos.logback.*",
"org.slf4j.*" })
public class MyTestClass{
@Test
public void signup(){
this.company = userService.saveCompany(company);
this.user.setCompany(company);
this.user = userService.saveUser(this.user); // gives exception
}
}
*3- Save methods:*
@Transactional(propagation = Propagation.REQUIRED)
public User saveUser(User user) {
return userRepository.saveAndFlush(user); //JpaRepository
}
@Transactional(propagation = Propagation.REQUIRED)
public Company saveCompany(Company company) {
return companyRepository.saveAndFlush(company); //JpaRepository
}
*4- JPA Config*
@Configuration
@EnableSpringConfigured
public class SpringJNDIJPAConfig {
protected static final Logger logger =
LoggerFactory.getLogger(SpringConfig.class);
protected static final String HIBERNATE_TRANSACTION_JTA_PLATFORM =
"hibernate.transaction.jta.platform";
@Value("${hibernate.naming_strategy:org.hibernate.cfg.DefaultNamingStrategy}")
private String namingStrategy;
@Value("${hibernate.packages_to_scan:com.myapp.data.domain}")
private String packagesToScan;
@Value("${spring_config.project_name}")
private String projectName;
@Value("${hibernate.show_sql:false}")
private String showSql;
@Value("${hibernate.hbm2ddl.auto:update}")
private String hbm2ddlAuto;
@Value("${hibernate.format_sql:false}")
private String formatSql;
@Value("${hibernate.dialect:org.hibernate.dialect.MySQL5InnoDBDialect}")
private String hibernateDialect;
@Value("${hibernate.connection.useUnicode:true}")
private String useUnicode;
@Value("${hibernate.connection.characterEncoding:UTF-8}")
private String characterEncoding;
@Value("${hibernate.charSet:UTF-8}")
private String charSet;
@Value("${hibernate.default_schema}")
private String defaultSchema;
@Value("${hibernate.use_default_schema:true}")
private boolean useDefaultSchema;
@Value("${hibernate.use_sql_comments:true}")
private String useSqlComments;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private DataSource dataSource;
@Bean
public HibernateExceptionTranslator hibernateExceptionTranslator() {
return new HibernateExceptionTranslator();
}
@Bean
protected EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean bean = new
LocalContainerEntityManagerFactoryBean();
JtaPersistenceUnitManager puManager = new JtaPersistenceUnitManager();
Map<String, DataSource> dataSources = new HashMap<String,
DataSource>();
dataSources.put("dataSource", dataSource);
puManager.setDataSourceLookup(new MapDataSourceLookup(dataSources));
puManager.setDefaultDataSource(dataSource);
puManager.setPackagesToScan(packagesToScan());
bean.setPersistenceUnitManager(puManager);
bean.setPersistenceProviderClass(HibernatePersistence.class);
bean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
Properties jpaProperties = getHibernateProperties();
jpaProperties.put(HIBERNATE_TRANSACTION_JTA_PLATFORM,
SpringJtaPlatform.class.getName().toString());
bean.setJpaProperties(jpaProperties);
puManager.afterPropertiesSet();
bean.afterPropertiesSet();
return bean.getObject();
}
protected String getDefaultSchema() {
String ds = ConfigurationUtil.config().getString("db.schema.name");
if (ds != null) defaultSchema = ds;
return defaultSchema;
}
protected String getUseUnicode() {
return useUnicode;
}
protected String getCharacterEncoding() {
return characterEncoding;
}
protected String getCharSet() {
return charSet;
}
protected String getFormatSql() {
return formatSql;
}
protected String getHbm2ddlAuto() {
return hbm2ddlAuto;
}
protected String getHibernateDialect() {
return hibernateDialect;
}
protected Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", getHibernateDialect());
properties.put("hibernate.hbm2ddl.auto", getHbm2ddlAuto());
properties.put("hibernate.show_sql", getShowSql());
properties.put("hibernate.use_sql_comments", getUseSqlComments());
properties.put("hibernate.format_sql", getFormatSql());
if(useDefaultSchema) {
properties.put("hibernate.default_schema", getDefaultSchema());
}
//properties.put("hibernate.ejb.naming_strategy", namingStrategy);
properties.put("hibernate.hbm2ddl.import_files", "/import.sql");
//properties.put("hibernate.connection.characterEncoding",
getCharacterEncoding());
//properties.put("hibernate.connection.charSet", getCharSet());
//properties.put("hibernate.connection.useUnicode", getUseUnicode());
if(logger.isInfoEnabled()) {
logger.info(MessageFormat.format("SET HIBERNATE PROPERTIES: {0}",
properties.toString()));
}
return properties;
}
protected String getProjectName() {
return projectName;
}
protected String getShowSql() {
return showSql;
}
protected String getUseSqlComments() {
return useSqlComments;
}
protected String packagesToScan() {
return packagesToScan;
}
@Bean
protected JtaTransactionManager transactionManager() {
SpringBeanFactory.setApplicationContext(applicationContext);
JtaTransactionManager manager = new JtaTransactionManager();
manager.setTransactionManagerName("java:jboss/TransactionManager");
manager.setUserTransactionName("java:jboss/UserTransaction");
manager.afterPropertiesSet();
return manager;
}
}
*ISSUE*: the code in test method works very fine when running the
application (local database), but when running it from test (in memory
database) it saves company and when trying to save user it gives the
exception:
org.springframework.dao.InvalidDataAccessApiUsageException: detached
entity passed to persist: com.myapp.data.domain.Company; nested exception
is org.hibernate.PersistentObjectException: detached entity passed to
persist: com.myapp.data.domain.Company
at
org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:668)
at
org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:106)
at
org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:403)
at
org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58)
at
org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at
org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at
org.springframework.data.jpa.repository.support.LockModeRepositoryPostProcessor$LockModePopulatingMethodIntercceptor.invoke(LockModeRepositoryPostProcessor.java:92)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.myapp.service.UserService.saveUser(UserService.java:95)
at
com.myapp.service.UserService$$FastClassByCGLIB$$697e2a1b.invoke(<generated>)
at
org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
at
com.myapp.service.UserService$$EnhancerByCGLIB$$83ca6add.saveUser(<generated>)
at com.myapp.web.controllers.SignUpBean.signup(SignUpBean.java:226)
at
test.myapp.web.controllers.SignUpBeanTest.testSignUpProcess(SignUpBeanTest.java:124)
at
org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at
org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at
org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at
org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.hibernate.PersistentObjectException: detached entity
passed to persist: com.myapp.data.domain.Company
at
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:141)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:842)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:835)
at
org.hibernate.ejb.engine.spi.EJB3CascadingAction$1.cascade(EJB3CascadingAction.java:53)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:387)
at
org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:330)
at
org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
at
org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:424)
at
org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:263)
at
org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192)
at
org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:135)
at
org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78)
at
org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208)
at
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151)
at
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:78)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:852)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:826)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:830)
at
org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:875)
at
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:241)
at
org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:354)
at
org.springframework.data.jpa.repository.support.SimpleJpaRepository.saveAndFlush(SimpleJpaRepository.java:368)
at
org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:333)
at
org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:318)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at
org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
... 33 more
--
You received this message because you are subscribed to the Google Groups "H2
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/groups/opt_out.