PostgreSQL + OpenJPA:调用persist()时的异常

时间:2018-06-07 13:39:38

标签: postgresql jpa

我使用OpenJPA 2.4.2从ejb访问PostgreSQL数据库。

当调用persist(参见下面的代码)时,我得到以下异常:

<openjpa-2.4.2-r422266:1777108 fatal general error> org.apache.openjpa.persistence.PersistenceException: user lacks privilege or object not found: NEXTVAL {SELECT NEXTVAL('employee_id_seq')} [code=-5501, state=42501]
org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:5003)
org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4963)
org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:133)
org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:107)
org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:59)
org.apache.openjpa.jdbc.kernel.AbstractJDBCSeq.next(AbstractJDBCSeq.java:63)
org.apache.openjpa.util.ImplHelper.generateValue(ImplHelper.java:159)
org.apache.openjpa.util.ImplHelper.generateFieldValue(ImplHelper.java:143)
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.assignField(JDBCStoreManager.java:774)
org.apache.openjpa.util.ApplicationIds.assign(ApplicationIds.java:492)
org.apache.openjpa.util.ApplicationIds.assign(ApplicationIds.java:468)
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.assignObjectId(JDBCStoreManager.java:758)
org.apache.openjpa.kernel.DelegatingStoreManager.assignObjectId(DelegatingStoreManager.java:135)
org.apache.openjpa.kernel.StateManagerImpl.assignObjectId(StateManagerImpl.java:595)
org.apache.openjpa.kernel.StateManagerImpl.preFlush(StateManagerImpl.java:3051)
org.apache.openjpa.kernel.PNewState.beforeFlush(PNewState.java:44)
org.apache.openjpa.kernel.StateManagerImpl.beforeFlush(StateManagerImpl.java:1072)
org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2143)
org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2103)
org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:2021)
org.apache.geronimo.transaction.manager.TransactionImpl.beforeCompletion(TransactionImpl.java:527)
org.apache.geronimo.transaction.manager.TransactionImpl.beforeCompletion(TransactionImpl.java:512)
org.apache.geronimo.transaction.manager.TransactionImpl.beforePrepare(TransactionImpl.java:413)
org.apache.geronimo.transaction.manager.TransactionImpl.commit(TransactionImpl.java:262)
org.apache.geronimo.transaction.manager.TransactionManagerImpl.commit(TransactionManagerImpl.java:252)
org.apache.openejb.core.transaction.JtaTransactionPolicy.completeTransaction(JtaTransactionPolicy.java:331)
org.apache.openejb.core.transaction.TxRequired.commit(TxRequired.java:76)
org.apache.openejb.cdi.transactional.InterceptorBase.intercept(InterceptorBase.java:68)
org.apache.openejb.cdi.transactional.RequiredInterceptor.intercept(RequiredInterceptor.java:35)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.apache.webbeans.component.InterceptorBean.intercept(InterceptorBean.java:136)
org.apache.webbeans.intercept.InterceptorInvocationContext.proceed(InterceptorInvocationContext.java:63)
org.apache.webbeans.intercept.DefaultInterceptorHandler.invoke(DefaultInterceptorHandler.java:139)
com.virtualpairprogrammers.staffmanagement.dataaccess.EmployeeDataAccessImplementation$$OwbInterceptProxy0.insert(com/virtualpairprogrammers/staffmanagement/dataaccess/EmployeeDataAccessImplementation.java)
com.virtualpairprogrammers.staffmanagement.EmployeeManagementImplementation.registerEmployee(EmployeeManagementImplementation.java:22)
com.virtualpairprogrammers.backingbeans.AddEmployeeBean.AddEmployee(AddEmployeeBean.java:45)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.apache.el.parser.AstValue.invoke(AstValue.java:247)
org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:267)
org.apache.webbeans.el22.WrappedMethodExpression.invoke(WrappedMethodExpression.java:52)
org.apache.myfaces.view.facelets.el.ContextAwareTagMethodExpression.invoke(ContextAwareTagMethodExpression.java:96)
org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:74)
javax.faces.component.UICommand.broadcast(UICommand.java:120)
javax.faces.component.UIViewRoot._broadcastAll(UIViewRoot.java:1174)
javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:365)
javax.faces.component.UIViewRoot._process(UIViewRoot.java:1660)
javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:864)
org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:42)
org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:196)
org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:143)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:198)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.apache.openejb.server.httpd.EEFilter.doFilter(EEFilter.java:65)

以下是我如何调用persist并定义持久化上下文:

@Transactional
public class EmployeeDataAccessImplementation implements EmployeeDataAccess
{
    @PersistenceContext(unitName = "EmployeeDB")
    private EntityManager em;

    ...

    public void insert(Employee newEmployee) {
        em.persist(newEmployee);
    }
}

以下是我在persistence.xml中配置持久性单元EmployeeDB的方法:

<?xml version="1.0"?>
<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_2_0.xsd"
         version="2.0">
<persistence-unit name="EmployeeDB">

    <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>

    <class>com.virtualpairprogrammers.staffmanagement.domain.Employee</class>

    <properties>
        <property name="persistence.openjpa.ConnectionDriverName" value="org.postgresql.Driver"/>
        <property name="persistence.openjpa.ConnectionURL" value="jdbc:postgresql://localhost:5432/EmployeeDB"/>
        <property name="persistence.openjpa.ConnectionUserName" value="postgres"/>
        <property name="persistence.openjpa.ConnectionPassword" value="test"/>
        <property name="openjpa.Log" value="SQL=TRACE"/>
        <property name="openjpa.jdbc.DBDictionary" value="postgres(SchemaCase=lower)"/>
    </properties>
</persistence-unit>

最后,这是我如何将类Employee映射到数据库表Employee:

@Entity(name="employee")
public class Employee {
    @Id
    @GeneratedValue (strategy = GenerationType.SEQUENCE, generator="employee_gen")
    @SequenceGenerator (name="employee_gen", sequenceName="employee_id_seq", allocationSize=1)
    @Getter @Setter    
    private Long id;

    ...
    public Employee() {}
}

我使用以下SQL命令创建了序列employee_id_seq:

create sequence employee_id_seq;

以防万一我更改了所有者并将employee_id_seq上的所有权限授予postgres:

alter sequence public.employee_id_seq OWNER TO postgres;
GRANT USAGE, SELECT ON SEQUENCE employee_id_seq TO postgres;

感谢您的帮助。

0 个答案:

没有答案