2
votes

I'm using GlassFish 4, Spring and PostgreSQL. I would like to save an entity to a database, but when I try, I get an exception:

javax.transaction.RollbackException: Transaction marked for rollback. at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:445) at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.commit(JavaEETransactionManagerSimplified.java:854) at com.sun.enterprise.transaction.UserTransactionImpl.commit(UserTransactionImpl.java:212) at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1021) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730) at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653) at com.amleto.server.services.controllers.AmletoController$$EnhancerBySpringCGLIB$$6d3cf30.facebookDebug() at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:111) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282) at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167) at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201) at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175) at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235) at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201) at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133) at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112) at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561) at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545) at java.lang.Thread.run(Thread.java:722)

Actually this means nothing to me. I don't even know where to look, because the message is not very descriptive. Do you know how to retrieve more info on this exception? Or what could be the reason to invoke it?

persistence.xml:

<?xml version="1.0" encoding="UTF-8"?><persistence version="2.0" 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_2_0.xsd">
<persistence-unit name="amleto-server-model" transaction-type="JTA">
    <jta-data-source>jdbc/amleto</jta-data-source>
    <class>com.amleto.server.model.entities.FacebookDebug</class>
    <properties>
        <property name="openjpa.jdbc.Schema" value="public"/>
        <property name="openjpa.TransactionMode" value="managed" />
        <property name="openjpa.ConnectionFactoryMode" value="managed" />
        <property name="openjpa.jdbc.DBDictionary" value="postgres" />
        <!-- Log all queries performed against the database. -->
        <!-- Do not use in production, this will generate a lot of output. -->
        <property name="openjpa.Log" value="SQL=TRACE"/>
    </properties>
</persistence-unit>

AmletoController.java:

package com.amleto.server.services.controllers;

import java.sql.Timestamp;
import java.util.GregorianCalendar;

import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.amleto.server.model.entities.FacebookDebug;
import com.amleto.server.services.utils.SharedEntityManager;

@Controller
public class AmletoController {

    @Autowired
    SharedEntityManager entityManager;

    @Transactional
    @ResponseBody
    @RequestMapping(value = "/facebookDebug", method=RequestMethod.GET)
    public String facebookDebug(@RequestParam(value="action", required=true) String action, 
                                @RequestParam(value="userId", required=true) String userId) {

            FacebookDebug fb = new FacebookDebug();
            fb.setAction(action);
            fb.setUserId(userId);
            GregorianCalendar dateCreate = new GregorianCalendar();
            fb.setDateCreate(new Timestamp(dateCreate.getTimeInMillis()));
            entityManager.getEntityManager().persist(fb);

            /*
            int returnValue = entityManager.getEntityManager().createNativeQuery("insert into facebook_debug (action, user_id, date_create) values(?,?,current_timestamp)")
                    .setParameter("1", action)
                    .setParameter("2", userId)
                    .executeUpdate();       
            */

            return "why it doesn't work?";
    }
}

FacebookDebug.java:

package com.amleto.server.model.entities;

import java.io.Serializable;
import javax.persistence.*;
import java.sql.Timestamp;


/**
 * The persistent class for the facebook_debug database table.
 * 
 */
@Entity
@Table(name="facebook_debug")
@NamedQuery(name="FacebookDebug.findAll", query="SELECT f FROM FacebookDebug f")
public class FacebookDebug implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="facebook_debug_id")
    private Integer facebookDebugId;

    private String action;

    @Column(name="date_create")
    private Timestamp dateCreate;

    @Column(name="user_id")
    private String userId;

    public FacebookDebug() {
    }

    public Integer getFacebookDebugId() {
        return this.facebookDebugId;
    }

    public void setFacebookDebugId(Integer facebookDebugId) {
        this.facebookDebugId = facebookDebugId;
    }

    public String getAction() {
        return this.action;
    }

    public void setAction(String action) {
        this.action = action;
    }

    public Timestamp getDateCreate() {
        return this.dateCreate;
    }

    public void setDateCreate(Timestamp dateCreate) {
        this.dateCreate = dateCreate;
    }

    public String getUserId() {
        return this.userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

}

SharedEntityManager.java:

package com.amleto.server.services.utils;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class SharedEntityManager implements ApplicationContextAware {
    private static ApplicationContext _appCtx;

    @PersistenceContext(name="amleto-server-model")
    private EntityManager em;

    private static SharedEntityManager instance;

    public static SharedEntityManager getInstance() {
        if(instance == null) {
            instance = new SharedEntityManager();
        }
        return instance;
    }

    public EntityManager getEntityManager() {
        if(this.em == null) {
            this.em = _appCtx.getBean(EntityManager.class);
        }
        return this.em;
    }

    @Override
    public void setApplicationContext(ApplicationContext appCtx) throws BeansException {
        _appCtx = appCtx;
    }
}

JDBC connection pool on the server seems to work ok (ping succeeds). I'm even able to generate JPA entitites from the tables in my project using this connection. PS. The commented code (native query) produces this error:

org.postgresql.util.PSQLException: ERROR: relation "facebook_debug" doesn't exist

But this entity exists. All names in my database are lowercase, entity mapping looks ok. Probably there is a problem with the schema selection but again, it looks ok in the configuration.

After adding this property to the persistence.xml:

<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>

I came back to the transaction rollback exception just linke in the above stack trace. After adding additional config to the GlassFish logging config I obtained following stack trace just before the exception:

[2015-09-21T18:36:15.256+0200] [glassfish 4.1] [CONFIG] [] [org.eclipse.persistence.session.file:/C:/glassfish4/glassfish/domains/domain2/eclipseApps/amleto-server-ear/amleto-server-services-ws_war/WEB-INF/lib/amleto-server-model-0.1.0-SNAPSHOT.jar_amleto-server-model.connection] [tid: _ThreadID=27 _ThreadName=http-listener-1(2)] [timeMillis: 1442853375256] [levelValue: 700] [[ connecting(DatabaseLogin( platform=>PostgreSQLPlatform user name=> "" connector=>JNDIConnector datasource name=>null ))]]

[2015-09-21T18:36:15.261+0200] [glassfish 4.1] [CONFIG] [] [org.eclipse.persistence.session.file:/C:/glassfish4/glassfish/domains/domain2/eclipseApps/amleto-server-ear/amleto-server-services-ws_war/WEB-INF/lib/amleto-server-model-0.1.0-SNAPSHOT.jar_amleto-server-model.connection] [tid: _ThreadID=27 _ThreadName=http-listener-1(2)] [timeMillis: 1442853375261] [levelValue: 700] [[ Connected: jdbc:postgresql://localhost/amleto?loglevel=0&prepareThreshold=5&preparedStatementCacheQueries=256&preparedStatementCacheSizeMiB=5&defaultRowFetchSize=0&binaryTransfer=true&compatible=9.4&readOnly=false&binaryTransferEnable=&binaryTransferDisable=&unknownLength=2147483647&logUnclosedConnections=false&disableColumnSanitiser=false&tcpKeepAlive=false&loginTimeout=0&connectTimeout=0&socketTimeout=0&receiveBufferSize=-1&sendBufferSize=-1&useSpnego=false&gsslib=auto&sspiServiceClass=POSTGRES&allowEncodingChanges=false&targetServerType=any&loadBalanceHosts=true&hostRecheckSeconds=10 User: postgres Database: PostgreSQL Version: 9.4.4 Driver: PostgreSQL Native Driver Version: PostgreSQL 9.4 JDBC4 (build 1202)]]

[2015-09-21T18:36:15.582+0200] [glassfish 4.1] [INFO] [] [org.eclipse.persistence.session.file:/C:/glassfish4/glassfish/domains/domain2/eclipseApps/amleto-server-ear/amleto-server-services-ws_war/WEB-INF/lib/amleto-server-model-0.1.0-SNAPSHOT.jar_amleto-server-model.connection] [tid: _ThreadID=27 _ThreadName=http-listener-1(2)] [timeMillis: 1442853375582] [levelValue: 800] [[ file:/C:/glassfish4/glassfish/domains/domain2/eclipseApps/amleto-server-ear/amleto-server-services-ws_war/WEB-INF/lib/amleto-server-model-0.1.0-SNAPSHOT.jar_amleto-server-model login successful]]

[2015-09-21T18:36:15.858+0200] [glassfish 4.1] [FINE] [] [org.eclipse.persistence.session.file:/C:/glassfish4/glassfish/domains/domain2/eclipseApps/amleto-server-ear/amleto-server-services-ws_war/WEB-INF/lib/amleto-server-model-0.1.0-SNAPSHOT.jar_amleto-server-model.sql] [tid: _ThreadID=27 _ThreadName=http-listener-1(2)] [timeMillis: 1442853375858] [levelValue: 500] [[ insert into facebook_debug (action, user_id, date_create) values(?,?,current_timestamp) bind => [2 parameters bound]]]

1
Please update the question with your persistence.xml and the code of com.amleto.server.services.controllers.AmletoController.unwichtich
I have updated my question. Please look now and tell me if you I have to provide more info.Jacek

1 Answers

0
votes

I would guess the problem is caused by the table which can't be found but I don't see the exact reason at the moment.

You can try the following:

Add this in your persistence.xml:

<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>

It should instruct OpenJPA to create the tables which don't exist. Maybe this will show you, where the table was expected to be.

Update #1:

You can try to print the nested exception stacktrace like this:

    try {
        entityManager.getEntityManager().persist(fb);
    } catch (Exception x) {

        if (x.getCause() != null) {
            x.getCause().printStackTrace();

            if (x.getCause().getCause() != null) {
                x.getCause().getCause().printStackTrace();
            }
        }
    }