4
public void miseAJourTranscoIdCroisiere(Integer idCroisiereKaravel, String idCroisiereArmateur, TypeArmateur typeArmateur) {
        IdCroisiereKaravelArmateur idRelationship = new IdCroisiereKaravelArmateur();

        idRelationship.setIdCroisiereKaravel(idCroisiereKaravel);
        idRelationship.setIdCroisiereArmateur(idCroisiereArmateur);
        idRelationship.setTypeArmateur(typeArmateur);

        entityManager.persist(idRelationship);
    }

Is this code snippet supposed to work by itslf? It throws no exception. However it does nothing. I'm more than confused with the persistence in Java.

Since I can't do insert ... values with hql, I'm supposed to do it with jpa directly, right?

I tried to do it in this way but I got this

java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:198)
    at $Proxy19.getTransaction(Unknown Source)
    at com.karavel.connectivity.gateway.croisiere.common.repository.impl.CatalogueKaravelRepositoryImpl.miseAJourTranscoIdCroisiere(CatalogueKaravelRepositoryImpl.java:56)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:196)
    at $Proxy23.miseAJourTranscoIdCroisiere(Unknown Source)
    at com.karavel.connectivity.gateway.croisiere.controller.service.RechercherCroisiereController.getItineraireCroisiere(RechercherCroisiereController.java:385)
    at com.karavel.connectivity.gateway.croisiere.controller.service.RechercherCroisiereController.obtenirListeCroisiere(RechercherCroisiereController.java:283)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.AbstractRequestLoggingFilter.doFilterInternal(AbstractRequestLoggingFilter.java:193)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:291)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:662)

So I thought about creating another EntityManager for doing this. But sinde it's not a static method I can't use EntityManagerFactory.

Can be so messy to do a simple insert in the ddbb?

I'm so sorry if I say foolish or I mix concepts, but I have two days experience in Java persistence and Hibernate.

Edit to show my classes :

I Do need a transaction, but I can't have it from a shared EntityManager (what does that means?)

Do I need a EntityManager for just that method? If I do, I can't use EntityManagerFactory for being static.

I'm sorry, it wasn't me creating this architecture. I'm just starting with Spring and Hibernate, so there's a big mix here for me...

ApplicationContext:

<bean id="gateway.croisiere.catalogueKaravel.dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${gateway.croisiere.catalogueKaravel.driver.className}" />
    <property name="url" value="${gateway.croisiere.catalogueKaravel.driver.url}" />
    <property name="username" value="${gateway.croisiere.catalogueKaravel.driver.username}" />
    <property name="password" value="${gateway.croisiere.catalogueKaravel.driver.password}" />
</bean>
<bean id="gateway.croisiere.catalogueKaravel.entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceXmlLocation" value="classpath:/catalogueKaravel-persistence.xml" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="generateDdl" value="${gateway.croisiere.catalogueKaravel.hibernate.hbm2ddl.auto}" />
            <property name="databasePlatform" value="${gateway.croisiere.catalogueKaravel.hibernate.dialect}" />
            <property name="showSql" value="${gateway.croisiere.catalogueKaravel.hibernate.show_sql}" />
        </bean>
    </property>
    <property name="dataSource" ref="gateway.croisiere.catalogueKaravel.dataSource" />
    <property name="persistenceUnitName" value="gateway-croisiere-catalogueKaravel-persitence-unit" />
</bean>
<bean id="gateway.croisiere.catalogueKaravel.transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="gateway.croisiere.catalogueKaravel.entityManagerFactory" />
    <property name="defaultTimeout" value="${gateway.croisiere.catalogueKaravel.hibernate.transaction.timeout}" />
</bean>
<tx:annotation-driven transaction-manager="gateway.croisiere.catalogueKaravel.transactionManager" />persistence:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
    <persistence-unit name="gateway-croisiere-catalogueKaravel-persitence-unit" transaction-type="RESOURCE_LOCAL">
        <class>com.karavel.connectivity.gateway.croisiere.common.domain.cataloguekaravel.IdCroisiereKaravelArmateur</class>
        <class>com.karavel.connectivity.gateway.croisiere.common.domain.cataloguekaravel.CroisiereInfoCatalogueKaravel</class>
        <class>com.karavel.connectivity.gateway.croisiere.common.domain.cataloguekaravel.CroisiereOffreItineraireCatalogueKaravel</class>
        <class>com.karavel.connectivity.gateway.croisiere.common.domain.cataloguekaravel.EscaleCatalogueKaravel</class>
        <class>com.karavel.connectivity.gateway.croisiere.common.domain.cataloguekaravel.CroisiereItineraireCatalogueKaravel</class>
    </persistence-unit>
</persistence>

Entity:

@Entity
@Table(name="transco_idcroisierekaravel_idcroisierearmateur")
public class IdCroisiereKaravelArmateur implements Serializable {

    private static final long serialVersionUID = -2764921376397148157L;

    @Id
    @GeneratedValue
    @Column(name="id")
    private Integer id;

    @Column(name="idCroisiereKaravel")
    private Integer idCroisiereKaravel;

    @Column(name="idCroisiereArmateur")
    private String idCroisiereArmateur;

    @Column(name="typeArmateur")
    @Enumerated(EnumType.STRING)
    private TypeArmateur typeArmateur;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getIdCroisiereKaravel() {
        return idCroisiereKaravel;
    }

    public void setIdCroisiereKaravel(Integer idCroisiereKaravel) {
        this.idCroisiereKaravel = idCroisiereKaravel;
    }

    public String getIdCroisiereArmateur() {
        return idCroisiereArmateur;
    }

    public void setIdCroisiereArmateur(String idCroisiereArmateur) {
        this.idCroisiereArmateur = idCroisiereArmateur;
    }

    public TypeArmateur getTypeArmateur() {
        return typeArmateur;
    }

    public void setTypeArmateur(TypeArmateur typeArmateur) {
        this.typeArmateur = typeArmateur;
    }
}

Repository

@SuppressWarnings("unchecked")
public class CatalogueKaravelRepositoryImpl implements CatalogueKaravelRepository {
    @PersistenceContext(unitName="gateway-croisiere-catalogueKaravel-persitence-unit")
    private EntityManager entityManager;

    @Override
    @Transactional
    public void miseAJourTranscoIdCroisiere(Integer idCroisiereKaravel, String idCroisiereArmateur, TypeArmateur typeArmateur) {

        IdCroisiereKaravelArmateur idRelationship = new IdCroisiereKaravelArmateur();

        idRelationship.setIdCroisiereKaravel(idCroisiereKaravel);
        idRelationship.setIdCroisiereArmateur(idCroisiereArmateur);
        idRelationship.setTypeArmateur(typeArmateur);

        EntityManager em = getEntityManager();

        // begin transaction 
        em.getTransaction().begin();

        // persist object - add to entity manager
        em.persist(idRelationship);

        // flush em - save to DB
        em.flush();

        // commit transaction at all
        em.getTransaction().commit();   
    }
}
Community
  • 1
  • 1
luso
  • 2,812
  • 6
  • 35
  • 50
  • 1
    If you were able to solve the problem on your own, you should write it up and accept that answer! On Stack Overflow, you shouldn't really be putting the answer as an addendum to the question. – Hannele Apr 04 '13 at 18:56

3 Answers3

4

Looks like your problem is simple: it wants a transaction. You are using Spring. The main reason to drag Spring into the persistence realm is to get the AOP-based injected transactions.. ? You should be able to annotate your method @Transaction and have the TransactionManager started up either in your applicationContext.xml or through some other bootstrap.

Rob
  • 11,446
  • 7
  • 39
  • 57
  • Hi Rob, thanks for the suggestion. The problem is that I think that's already done. Could you check my update? – luso May 28 '12 at 08:56
  • And you are getting the same error? Why are you doing the transaction manually (it's ok, but then there's no reason to have Spring here that I can see)? I doubt you are getting the same error. – Rob May 28 '12 at 12:29
  • thanks Rob. I do the transaction manually cause I don't really know what I'm doing... :P I'll try to get it working with Spring. Thanks for your help. – luso May 29 '12 at 07:49
  • dude, I am not knocking it. Frankly, the annotation-only approach has produced a generation of people who don't know what a transaction is and think there's a transaction fairy. I am trying to help. Are you getting a different error now? – Rob May 29 '12 at 13:57
  • Hi Rob, thank you so much for your help. but I think there's something else here... I've just asked for help to a Java architect from my company. He's been unable to detect the problem since yesterday, so I guess there's something deeper in any configuration file. I will let you know when I know something new. Thaks! – luso May 30 '12 at 13:56
  • I believe just in the fairies that took my socks away in the laundry, but I'll let you know if I see the Transaction's one :D – luso May 30 '12 at 13:56
2

Yes, EntityManager#persist should be able save records,

  1. Your entity manager persist seems to be throwing runtime exception wrap it in try catch Block

  2. Ensure that your class is declared under spring transaction, if you are using Annotation based configuration then your class should be marked @Transactional and your entityManager as @PersistenceContext

mprabhat
  • 20,107
  • 7
  • 46
  • 63
  • Hi mprabhat. Yes, I'm using Annotation, do I need to mark as Transactional the class or the method? – luso May 28 '12 at 08:58
  • Your class will be marked as @Transactional and your EntityManager should have @PersistenceContext annotation – mprabhat May 28 '12 at 09:14
  • Still not working. The EntityManager.persist() does nothing. If I EntityManager.flush() it ask for a transaction. Could you please check the update I did in the post? Might it help you to give me a clue... Thanks a lot! – luso May 28 '12 at 09:36
1

As stated by the original poster of the question:


My solution:

Actually the bean for the TranscationManager was not correctly set up. I took the first one found in the Spring config file. Since the audit system was working fine, I just used the same configuration. However, for other DDBB access it tried to use the Audit TransactionManager (the first one appearing in the config file)

I hope this helps someone. Sorry for such a vague solution, but this was several months ago and I'm not able to access the code anymore.

Hugo Dozois
  • 8,147
  • 12
  • 54
  • 58