i'm trying save entity in repository not work @ all. repository autowired , in runtime use saveandflush save entity. i'm using postgresql. above test methods added comments explanation going on. expected method saveandflush should work did not. can not find why.
@transactional public class testclass{ @autowired private myrepository repository; @autowired private entitymanager entitymanager; // working version public void writingtorepositoryworking() { entitymanager.gettransaction().begin(); entitymanager.persist(new mydata(99)); entitymanager.gettransaction().commit(); } // not working , throws exception : // transactionrequiredexception: no transaction in progress public void writingtorepositorynotworking() { repository.saveandflush(new mydata(99)); } // not working, no exception, no data in repository, // auto generated id incremented public void writingtorepositorynotworkingtoo() { repository.save(new mydata(99)); } }
repository interface file
@repository @transactional public interface myrepository extends jparepository<mydata, long> {}
mydata file
@entity(name = "mydata") public class mydata { @id @generatedvalue(strategy = generationtype.auto) long id; private int testvalue; public mydata() { } public bugdata(int testvalue) { this.testvalue = testvalue; } public long getid() { return id; } public int gettestvalue() { return testvalue; } }
applicationconfiguration file
@configuration @enablejparepositories("com.mypackage.app") @enabletransactionmanagement @propertysource("classpath:application.properties") @enablewebmvc class applicationconfiguration extends webmvcconfigurationsupport { @value("${jdbc.url}") private string key_jdbc_url; @value("${jdbc.username}") private string key_jdbc_username; @value("${jdbc.password}") private string key_jdbc_password; @bean public static propertysourcesplaceholderconfigurer propertysourcesplaceholderconfigurer() { return new propertysourcesplaceholderconfigurer(); } @bean @autowired public localsessionfactorybean sessionfactory(datasource datasource) { localsessionfactorybean factory = new localsessionfactorybean(); factory.setdatasource(datasource); factory.setpackagestoscan("com.mypackage.app"); factory.sethibernateproperties(hibernateproperties()); return factory; } public properties hibernateproperties() { properties properties = new properties(); properties.setproperty("hibernate.dialect", "org.hibernate.dialect.postgresqldialect"); properties.setproperty("hibernate.show_sql", "true"); properties.setproperty("hibernate.hbm2ddl.auto", "update"); return properties; } @bean @autowired public hibernatetransactionmanager transactionmanager(sessionfactory sessionfactory) { return new hibernatetransactionmanager(sessionfactory); } @bean public datasource datasource() { basicdatasource datasource = new basicdatasource(); datasource.setdriverclassname("org.postgresql.driver"); datasource.seturl(key_jdbc_url); datasource.setusername(key_jdbc_username); datasource.setpassword(key_jdbc_password); return datasource; } @bean public entitymanagerfactory entitymanagerfactory() { localcontainerentitymanagerfactorybean em = new localcontainerentitymanagerfactorybean(); em.setdatasource(datasource()); em.setpackagestoscan("com.mypackage.app"); em.setjpavendoradapter(new hibernatejpavendoradapter()); em.setjpaproperties(hibernateproperties()); em.afterpropertiesset(); return em.getobject(); } @bean public entitymanager entitymanager(entitymanagerfactory entitymanagerfactory) { return entitymanagerfactory.createentitymanager(); } ... }
for starter, you're working on 2 different entitymanager in non-working test case: 1 entitymanager autowired test spring (this 1 singleton , should avoided anyway) , 1 entitymanager created entitymanagerfactory configured in applicationconfiguration. @ same time, have session running along side aforementioned 2 entitymanagers due configuration of hibernate sessionfactory. additionally, because of configured hibernatetransactionmanager, transactions created @transactional bound hibernate's session created sessionfactory , entitymanager used repository has no way know it. why transactionrequiredexception thrown when repository tried persist data.
to fix it, may consider removing hibernate's sessionfactory , switch transaction manager jpatransactionmanager. then, @transactional on repository have effect of creating new transaction , binding existing entitymanager known spring.
one side note @transactional on testclass doesn't @ instance of class not instantiated , managed spring. make work, proper configuration of transactional test class needs provided described here: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/testing.html.
hope helps.
Comments
Post a Comment