java - spring mvc + jpa + hibernate + transaction issue -


i seem unable persist data in db using injected entitymgr in spring mvc. have seen multiple similar questions (like entitymanager cannot use persist save element database) , none of answers seem solve issue. here config:

<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"  xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"  xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemalocation="  http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd  http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx.xsd  http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop.xsd  http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-3.1.xsd">  <!-- datasource --> <bean id="datasource" class="org.apache.commons.dbcp.basicdatasource"     destroy-method="close"      p:driverclassname="${driver}"     p:url="${url}"      p:username="contact" p:password="contact" /> <context:property-placeholder location="classpath:jdbc.properties" />  <bean id="entitymanagerfactory"     class="org.springframework.orm.jpa.localcontainerentitymanagerfactorybean"     p:datasource-ref="datasource"      p:packagestoscan="com.rd.web"> <!-- scans entities (model) -->     <property name="persistenceprovider">         <bean class="org.hibernate.ejb.hibernatepersistence" />     </property>     <property name="jpaproperties">         <props>             <prop key="hibernate.dialect">                 org.hibernate.dialect.mysql5dialect             </prop>             <prop key="hibernate.show_sql">true</prop>         </props>     </property> </bean>  <bean id="transactionmanager"   class="org.springframework.orm.jpa.jpatransactionmanager"     p:entitymanagerfactory-ref="entitymanagerfactory" /> <tx:annotation-driven transaction-manager="transactionmanager"/>  <context:component-scan base-package="com.rd.web" />  <bean id="contactservice" class="com.rd.web.service.contactserviceimpl"/> </beans> 

i have following code in (was in web controller moved service testing):

test_case1 (using spring transaction):

@transactional public contact setcontact(contact c){                if(c.getid() == null){             getemgr().persist(c);            }else{             getemgr().merge(c);         }         return c; } 

==> no error, entity isn't inserted, no insert statement in log.

test_case2 (using spring transaction):

@transactional public contact setcontact(contact c){                if(c.getid() == null){             getemgr().persist(c);            }else{             getemgr().merge(c);         }                     getemgr().flush();         return c; } 

==> exception got: no transaction in progress

test_case3:

    public contact setcontact(contact c){     getemgr().gettransaction().begin();     try{         if(c.getid() == null){             getemgr().persist(c);                        }else{             getemgr().merge(c);         }         getemgr().flush();         getemgr().gettransaction().commit();         return c;     }catch(throwable t){         getemgr().gettransaction().setrollbackonly();     }     return null; } 

==> throws error: java.lang.illegalstateexception: not allowed create transaction on shared entitymanager - use spring transactions or ejb cmt instead

it should not spring aop issue since operation public , called component (in service injected). appcontext defines transactions annotion driver . don't why transactions not started.

when use same applicationcontext.xml , trigger testclass loads contactservice , creates contact, contact saved correctly.

also have added following filter in web.xml, no avail:

<filter>     <filter-name>springopenentitymanagerinviewfilter</filter-name>     <filter-class>org.springframework.orm.jpa.support.openentitymanagerinviewfilter</filter-class> </filter> <filter-mapping>     <filter-name>springopenentitymanagerinviewfilter</filter-name>     <url-pattern>/*</url-pattern> </filter-mapping> 

any hints appreciated. cheers.

added information:

@muel, entitymgr being injected using persistencecontext:

@transactional 

@service("contactservice") public class contactserviceimpl implements icontactservice {

// @autowired // private ientitymgrprovider emgrpovider;

@persistencecontext entitymanager emgr;  @transactional public contact getcontactbyid(long id) {     return getemgr().find(contact.class, id); }  @transactional public list<contact> getallcontacts() {     typedquery<contact> qry = getemgr().createnamedquery("findall", contact.class);     return qry.getresultlist(); }  @transactional public contact setcontact(contact c){          if(c.getid() == null){             getemgr().persist(c); //              getemgr().flush();         }else{             getemgr().merge(c);         }         return c; }  @transactional(readonly=true) public void deletecontact(long id){     getemgr().remove(getemgr().find(contact.class, id));  }  private entitymanager getemgr(){ //      return emgrpovider.getemgr();     return emgr; }   public static void main(string[] args) {      classpathxmlapplicationcontext ctx = new classpathxmlapplicationcontext("appctx.xml");         icontactservice contactservice = ctx.getbean("contactservice", icontactservice.class);         contact c= new contact();         c.setbirthdate(new date());         c.setfirstname("p1");         c.setlastname("p2");          contactteldetail tel = new contactteldetail();         tel.setcontact(c);         tel.settelnumber("056776650");         tel.setteltype("landline");          c = contactservice.setcontact(c);          system.out.println(c.getid());  } } 

i realize getemgr() method not necessary emgr came somewhere else (where injected, nevermind now) btw, when run main method, can insert contact...

@user2264997 servlet context:

<?xml version="1.0" encoding="utf-8"?> 

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<!-- definition of root spring container shared servlets , filters --> <context-param>     <param-name>contextconfiglocation</param-name>     <param-value>/web-inf/spring/root-context.xml</param-value> </context-param>  <!-- creates spring container shared servlets , filters --> <listener>     <listener-class>org.springframework.web.context.contextloaderlistener</listener-class> </listener>  <!-- processes application requests --> <servlet>     <servlet-name>appservlet</servlet-name>     <servlet-class>org.springframework.web.servlet.dispatcherservlet</servlet-class>     <init-param>         <param-name>contextconfiglocation</param-name>         <param-value>/web-inf/spring/appservlet/servlet-context.xml</param-value>     </init-param>     <load-on-startup>1</load-on-startup> </servlet>  <servlet-mapping>     <servlet-name>appservlet</servlet-name>     <url-pattern>/</url-pattern> </servlet-mapping>  <filter>     <filter-name>encodingfilter</filter-name>     <filter-class>org.springframework.web.filter.characterencodingfilter</filter-class>     <init-param>         <param-name>encoding</param-name>         <param-value>utf-8</param-value>     </init-param>     <init-param>         <param-name>forceencoding</param-name>         <param-value>true</param-value>     </init-param> </filter>    <filter-mapping>     <filter-name>encodingfilter</filter-name>     <url-pattern>/*</url-pattern> </filter-mapping>  <filter>     <filter-name>springopenentitymanagerinviewfilter</filter-name>     <filter-class>org.springframework.orm.jpa.support.openentitymanagerinviewfilter</filter-class> </filter> <filter-mapping>     <filter-name>springopenentitymanagerinviewfilter</filter-name>     <url-pattern>/*</url-pattern> </filter-mapping>  </web-app> 

i have added last 2 filters testing. don't think should required (it seems last filter supporting lazy loading or something, tried anyway ...)

@martin frey

i'll have on something.

@mdeinum.wordpress.com

the service injected in webcontroller using @autowired. service implementation , web.xml see above. config file dispatcher servlet (allthough not seem have relevant information, maybe problem ;) ):

<?xml version="1.0" encoding="utf-8"?> <beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xsi:schemalocation="http://www.springframework.org/schema/mvc     http://www.springframework.org/schema/mvc/spring-mvc.xsd     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  <!-- dispatcherservlet context: defines servlet's request-processing infrastructure -->  <!--    use dispatcher servlet root --> <!--    <default-servlet-handler/> -->   <resources location="/, classpath:/meta-inf/web-resources/" mapping="/resources/**"/>  <interceptors>     <beans:bean class="org.springframework.web.servlet.theme.themechangeinterceptor"/>     <beans:bean class="org.springframework.web.servlet.i18n.localechangeinterceptor"         p:paramname="lang"/> </interceptors>  <beans:bean     class="org.springframework.ui.context.support.resourcebundlethemesource"     id="themesource" /> <beans:bean class="org.springframework.web.servlet.theme.cookiethemeresolver"     id="themeresolver" p:cookiename="theme" p:defaultthemename="standard" />   <beans:bean class="org.springframework.context.support.reloadableresourcebundlemessagesource"     id="messagesource" p:basenames="web-inf/i18n/messages,web-inf/i18n/application"     p:fallbacktosystemlocale="false" /> <beans:bean class="org.springframework.web.servlet.i18n.cookielocaleresolver"     id="localeresolver" p:cookiename="locale"/>   <!-- enables spring mvc @controller programming model --> <annotation-driven />  <!-- handles http requests /resources/** efficiently serving static resources in ${webapproot}/resources directory --> <!--    <resources location="/resources/" mapping="/resources/**" /> -->  <!-- resolves views selected rendering @controllers .jsp resources in /web-inf/views directory --> <!--    using tiles in stead ==> different view resolver --> <!--    <beans:bean    class="org.springframework.web.servlet.view.internalresourceviewresolver"> --> <!--        <beans:property name="prefix" value="/web-inf/views/" /> --> <!--        <beans:property name="suffix" value=".jsp" /> --> <!--    </beans:bean> -->  <context:component-scan base-package="com.rd.web" />  <!-- add following beans --> <!-- tiles configuration --> <beans:bean class="org.springframework.web.servlet.view.urlbasedviewresolver"     id="tilesviewresolver">     <beans:property name="viewclass"         value="org.springframework.web.servlet.view.tiles2.tilesview" /> </beans:bean> <beans:bean     class="org.springframework.web.servlet.view.tiles2.tilesconfigurer"     id="tilesconfigurer">     <beans:property name="definitions">         <beans:list>             <beans:value>/web-inf/layouts/layouts.xml</beans:value>             <!-- scan views directory tiles configurations -->             <beans:value>/web-inf/views/**/views.xml</beans:value>         </beans:list>     </beans:property> </beans:bean>  </beans:beans> 

i'll try configure hibernate adapter , let know how goes...

cheers

you duplicating component scanning in both applicationcontext.xml , servlet-context.xml.

<context:component-scan base-package="com.rd.web" /> 

when this, controller injected services picked component scan in servlet-context.xml not have transactions.

either explicitly specify controller packages base-package in servlet-context.xml, , non-controller packages base-package in applicatiocontext.xml.

or use exclude/include filter in component-scan declaration.

applicationcontext.xml

<context:component-scan ..>   <context:exclude-filter type="annotation" expression="org.springframework.stereotype.controller" />  ... 

in servlet-context.xml

<context:component-scan ..>   <context:include-filter type="annotation" expression="org.springframework.stereotype.controller" />  ... 

Comments

Popular posts from this blog

Unable to remove the www from url on https using .htaccess -