2012-05-17 29 views
5

İşlemlerde küçük bir sorunum var. Hazırda bekletme sağlayıcısı olan Spring 3.1.1.RELEASE, Spring Data 1.0.3.RELEASE JPA kullanıyorum. @Transactional ile açıklanmış bir yöntem olan bir junit testine başladığımda iyi görünüyor ama bütün bir uygulamaya başladığımda hata yok ama işlemler işe yaramıyor. İşte benim yapılandırmaları ve örnek kod:Spring, JPA işlemleri yalnızca JUnit testinde çalışır, ancak uygulamada değil

applicationContext.xml

<context:annotation-config /> 
    <context:component-scan base-package="com.sheedo.upload" /> 
    <jpa:repositories base-package="com.sheedo.upload.repository" /> 
    <tx:annotation-driven transaction-manager="transactionManager" /> 

    <bean 
     class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
     <property name="locations"> 
      <list> 
       <value>classpath*:messages/*.properties</value> 
       <value>classpath*:*.properties</value> 
      </list> 
     </property> 
    </bean> 

    <bean id="entityManagerFactory" 
     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <property name="persistenceUnitName" value="persistenceUnit" /> 
     <property name="dataSource" ref="dataSource" /> 
    </bean> 

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <property name="entityManagerFactory" ref="entityManagerFactory" /> 
    </bean> 

    <bean id="dataSource" class="com.mysql.jdbc.jdbc2.optional.MysqlDataSource"> 
     <property name="url" value="${jdbc.url}" /> 
     <property name="user" value="${jdbc.username}" /> 
     <property name="password" value="${jdbc.password}" /> 
    </bean> 

persistence.xml

<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider> 
    <properties> 
     <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" /> 
     <property name="hibernate.hbm2ddl.auto" value="update" /> 
     <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" /> 
     <property name="hibernate.connection.charSet" value="UTF-8" /> 
     <property name="hibernate.show_sql" value="true" /> 
    </properties> 
</persistence-unit> 

UserRepository.java

kamu interfa ce UserRepository JUnit testi Bu durumda CrudRepository < Kullanıcı, Uzun> {}

UserServiceImpl.java

@Service("userService") 
public class UserServiceImpl implements UserService { 

    @Autowired 
    private UserRepository userRepository; 

    @Override 
    @Transactional 
    public void addUser(String name, String surname) { 
     User u = new User(name, surname); 
     userRepository.save(u); 
     throw new RuntimeException(); // to invoke a rollback 
    } 
} 

UserServiceTest.java

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:/META-INF/spring/root-context.xml" }) 
public class UserServiceTest { 

    Logger log = LoggerFactory.getLogger(getClass()); 

    @Autowired 
    private UserService userService; 

    @Test 
    public void testUserAdd() { 
     userService.addUser("John", "Doe"); 
    } 

} 

uzanır işlem olayı çalışmıyor Hizmet yöntemi @Transactional ile açıklanmış olsa da. Ben testUserAdd() yönteme Bu açıklama eklemek zaman konsolda bu olsun: doğrudur

2012-05-17 11:17:54,208 INFO [org.springframework.test.context.transaction.TransactionalTestExecutionListener] - Rolled back transaction after test execution for test context [[[email protected] testClass = UserRepositoryTest, testInstance = [email protected], testMethod = [email protected], testException = java.lang.RuntimeException, mergedContextConfiguration = [[email protected] testClass = UserRepositoryTest, locations = '{classpath:/META-INF/spring/root-context.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader']]] 

herhalde. Yani, @Transactional ek açıklamanın sadece Junit test sınıfında çalışabilmesi mümkün olabilir, ancak diğerlerinde değil, fasulyelerde mi?

Benim teorim bu işlemin bir şekilde SpringJUnit4ClassRunner olmasıdır. İlkbahar yapılandırmamda işlemlerimin benim uygulamasında çalışmadığı, ancak yalnızca Junit test sınıflarında yanlış bir şey mi var? AppContext'te eksik bir şey var mı?

Düzenleme: günlüğü:

2012-05-17 12:46:10,770 DEBUG [org.springframework.orm.jpa.JpaTransactionManager] - Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 
2012-05-17 12:46:10,770 DEBUG [org.springframework.orm.jpa.JpaTransactionManager] - Opened new EntityManager [[email protected]] for JPA transaction 
2012-05-17 12:46:10,979 DEBUG [org.springframework.orm.jpa.JpaTransactionManager] - Not exposing JPA transaction [[email protected]] as JDBC transaction because JpaDialect [[email protected]] does not support JDBC Connection retrieval 
Hibernate: insert into user (name, surname) values (?, ?) 
2012-05-17 12:46:11,062 DEBUG [org.springframework.orm.jpa.JpaTransactionManager] - Initiating transaction commit 
2012-05-17 12:46:11,062 DEBUG [org.springframework.orm.jpa.JpaTransactionManager] - Committing JPA transaction on EntityManager [[email protected]] 
2012-05-17 12:46:11,142 DEBUG [org.springframework.orm.jpa.JpaTransactionManager] - Closing JPA EntityManager [[email protected]] after transaction 
2012-05-17 12:46:11,142 DEBUG [org.springframework.orm.jpa.EntityManagerFactoryUtils] - Closing JPA EntityManager 
+0

de component-scan yapılandırma nasıl işlemler "çalışmıyor" diye teşhis edersiniz? –

+0

Bu işlem yöntemini UserService'de hata ayıkladığında, yöntem istisna ile bitmiş olsa bile "userRepository.save (user)" ifadesinden sonra veritabanına varlık kaydedildi. Ve bu işlemde konsolda giriş yok. –

+0

"org.springframework.transaction" kaydedicilerini etkinleştirin. Bu daha fazla analizde yardımcı olacaktır. –

cevap

2

Ben tam olarak aynı problem vardı. Ayrıca, web yapılandırmamda <tx:annotation-driven/> etiketinin eklenmesi çözümünü okuyun (applicationContext.xml yerine spring-servlet.xml) ve benim için çalıştım.

Ama ... iyi bir çözüm, bu yüzden o neler olduğunu anlamaya çalıştı

dikkate Ve de yoktu, bu benim spring-servlet.xml vardı bir <context:component-scan> etiketi de @Service dahil olduğu ortaya çıktı taramasındaki sınıflar (base-package belirtimi çok genel). Bu garipti çünkü include-filter@Controller ek açıklamasına başvurmak yerine yerinde vardı ... ama yine de, web katmanının uygulama içeriğinin, applicationContext.xml için oluşturulan uygulama bağlamı yerine @Service örneklerini oluşturduğu görülüyor. İş katmanını tanımlayan kişi ... ve eskiden işlemselliğe izin vermediği için ... Hiçbir işlemim yoktu.

Çözüm (iyi bir): daha iyi (daha spesifik) spring-servlet.xml

+0

Aynı sorun vardı. Web uygulaması içeriği, filtreler tanımlanmış olsa bile yanlış fasulye yüklemesiydi. Ve açıkçası, web uygulaması bağlamında yoktu. Spring-servlet.xml (veya web layer applicationcontext adınız ne olursa olsun) yüklendiğinde ve bu deyimdeki günlüğüne baktığınızda günlüklerinizi denetleyin: "WebApplicationContext için Bean fabrikası" - web uygulamasının olup olmadığını görmek için bu fasulyeleri arayabilir bağlam yüklendi. –

İlgili konular