Я использую OpenJPA 2.4.2 для доступа к базе данных PostgreSQL из ejb.
При вызове 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);
}
}
Вот как я настраиваю модуль сохраняемости EmployeeDB в persistence.xml:
<?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() {}
}
Я создал последовательность employee_id_seq, используя следующую команду SQL:
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;
Буду признателен за вашу помощь.