2013-07-26 9 views
5

hafıza veritabanında H2 sürdürmeye geçti ve benim yapılandırma aşağıdaki gibidir:org.hibernate.PersistentObjectException: müstakil bir varlık i test için hafıza veritabanında H2 kullanıyorum

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{ 

    private Company company; 
    private User user; 


    @Test 
    public void signup(){ 

     User user = new User(); 
    Company company = new Company(); 
    company.setName("Test"); 
    company = usService.saveCompany(company); 
    user.setFirstName("Test"); 
    user.setLastName("User"); 
    user.setEmail("[email protected]"); 
    user.setPassword("verySecret"); 
    user.setCompany(company); 
    user = usService.saveUser(user); // gives exception 

    } 

} 

3- daha fazla yöntem:

@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 yapılandırma

@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; 
} 

} 

5- Kullanım Varlık:

@Entity 
@Table(name = "User", uniqueConstraints = { @UniqueConstraint(columnNames = { 
     "CompanyGID", "MPath" }) }) 
public class User extends PersistableEntity implements UserDetails { 
    /** 
    * 
    */ 
    private static final long serialVersionUID = -6520416613985790209L; 

    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    @JoinColumn(name = "CompanyGID") 
    private Company company; 

SAYI: test yönteminde kod uygulamayı çalıştırırken çok iyi çalışır (l Öçal JBoss üzerinde veritabanı) ve yedekleme fasulye yönteminden kod yürütmesini ama) hafıza veritabanında testi (onu çalıştıran bu şirket kaydeder ve kullanıcıyı kaydetmeye çalışırken o istisna verdiğinde:

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_aroundBody6(UserService.java:98) 
    at com.myapp.service.UserService$AjcClosure7.run(UserService.java:1) 
    at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:59) 
    at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:65) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260) 
    at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:63) 
    at com.myapp.service.UserService.saveUser(UserService.java:93) 
    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$$abc2864a.saveUser(<generated>) 
    at test.myapp.web.controllers.SignUpBeanTest.testSignUp(SignUpBeanTest.java:126) 
    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) 
    ... 38 more 
+0

bazı koddur sınavında eksik. Şirket nedir – ben75

cevap

10

Sorunun düşünüyorum burada:

@Test 
    public void signup(){ 

    User user = new User(); 
    Company company = new Company(); 
    company.setName("Test"); 
    company = usService.saveCompany(company); //object is saved and transaction is closed, so company is detached here. 
    user.setFirstName("Test"); 
    user.setLastName("User"); 
    user.setEmail("[email protected]"); 
    user.setPassword("verySecret"); 
    user.setCompany(company); //u are setting this detached object to user, NOTE user object's company attr is cascade.all which means this company will be saved as well when you save user. 
    user = usService.saveUser(user); // gives exception, because you are saving new user object with detached company object. 

    } 

Peki bunu nasıl çözeceğiz? Sen açıkça şirketi kurtarmak kalmamak cascade.all kullanıcı şirket nesne için üzerinde olduğu için kullanıcı, şirket nesneyi kaydetmek sağlayabilirsiniz, şirketin yanı kullanıcı kaydediliyor zaman kaydedilmelidir:

@Test 
    public void signup(){ 

    User user = new User(); 
    Company company = new Company(); 
    company.setName("Test"); 
    user.setFirstName("Test"); 
    user.setLastName("User"); 
    user.setEmail("[email protected]"); 
    user.setPassword("verySecret"); 
    user.setCompany(company); 
    user = usService.saveUser(user); // gives exception 

    } 
+0

tamam bunu deneyeceğim, ama garip olan şu ki, bu tam olarak aynı adımları adım atmak çok iyi çalışıyor (jboss üzerinde uygulamayı çalıştırdığımda ve yöntemi çağırdığımda) geliştirme modunda hiçbir sorun değil, ama sadece testte istisna veriyor fikirler? –

+1

doğru, sorunu çözdü, ama beni şaşırtan bu başarısız kod yönetilen fasulye eylem yönteminde iyi çalışıyor ve sadece test başarısız olur !!!!!!!!!!! 1 –

+0

eğer 'public void signup() 'işlem olarak işaretlenir, başarısız olmaz. durum böyle olabilir. – Elbek