javax.persistence.PersistenceException:org.hibernate.PropertyAccessException:无法通过Entity.id的反射getter获取字段值

时间:2015-01-04 23:19:11

标签: hibernate jpa

我有以下实体:

@Entity
public class Employee implements Serializable{
    private static final long serialVersionUID = 3454567L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int empId;

    @Column
    private String username;

    public int getEmpId() {
        return empId;
    }

    public void setEmpId(int empId) {
        this.empId = empId;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}

以下EJB:

public class UserDAO implements UserDAOInterface{

    @PersistenceContext(unitName = "MainPersistenceUnit")
    private EntityManager em;

    @Override
    public void persist(Employee sdf) {
        try {
            em.persist(sdf);
        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", e);
            throw new RuntimeException(e);
        }
    }
}

当调用persist时,抛出具有以下根本原因的异常:

Caused by: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.mine.projs.library.entity.Employee.empId
    at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:60)
    at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:346)
    at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4746)
    at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:4465)
    at org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:243)
    at org.hibernate.event.internal.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:511)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:116)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
    ... 100 more

以下是GlassFish 4.1的完整日志:

Info:   HHH000204: Processing PersistenceUnitInfo [
    name: MainPersistenceUnit
    ...]
Info:   HHH000412: Hibernate Core {4.3.7.Final}
Info:   HHH000206: hibernate.properties not found
Info:   HHH000021: Bytecode provider name : javassist
Info:   HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
Info:   HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
Info:   HHH000397: Using ASTQueryTranslatorFactory
Info:   HHH000227: Running hbm2ddl schema export
Info:   Hibernate: drop table if exists Employee
Info:   Hibernate: create table Employee (empId integer not null auto_increment, username varchar(255), primary key (empId)) ENGINE=InnoDB
Info:   HHH000230: Schema export complete
Info:   Portable JNDI names for EJB UserService: [java:global/Library/UserService, java:global/Library/UserService!com.mine.projs.library.service.interfaces.UserServiceInterface]
WARN:   WELD-000411: Observer method [BackedAnnotatedMethod] private org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN:   WELD-000411: Observer method [BackedAnnotatedMethod] public org.glassfish.jms.injection.JMSCDIExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN:   WELD-000411: Observer method [BackedAnnotatedMethod] org.glassfish.sse.impl.ServerSentEventCdiExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>, BeanManager) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
Info:   Initializing Mojarra 2.2.7 ( 20140610-1547 https://svn.java.net/svn/mojarra~svn/tags/2.2.7@13362) for context '/libr'
Info:   Running on PrimeFaces 5.1
Info:   Loading application [Library] at [/libr]
Info:   Library was successfully deployed in 3,429 milliseconds.
Info:   inside getAna
Info:   inside Create User
Severe:   exception caught
javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.mine.projs.library.entity.Employee.empId
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1187)
    at com.sun.enterprise.container.common.impl.EntityManagerWrapper.persist(EntityManagerWrapper.java:287)
    at com.mine.projs.library.dao.UserDAO.persist(UserDAO.java:20)
    at com.mine.projs.library.service.UserService.createUSer(UserService.java:21)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
    at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
    at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4786)
    at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
    at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:46)
    at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52)
    at sun.reflect.GeneratedMethodAccessor103.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:140)
    at sun.reflect.GeneratedMethodAccessor151.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
    at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:369)
    at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4758)
    at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4746)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
    at com.sun.proxy.$Proxy321.createUSer(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.jboss.weld.util.reflection.Reflections.invokeAndUnwrap(Reflections.java:414)
    at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:127)
    at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56)
    at org.jboss.weld.bean.proxy.InjectionPointPropagatingEnterpriseTargetBeanInstance.invoke(InjectionPointPropagatingEnterpriseTargetBeanInstance.java:65)
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:100)
    at com.mine.projs.library.service.UserServiceInterface$243194531$Proxy$_$$_Weld$EnterpriseProxy$.createUSer(Unknown Source)
    at com.mine.projs.library.view.UserBean.getAna(UserBean.java:29)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at javax.el.BeanELResolver.getValue(BeanELResolver.java:363)
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:140)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:204)
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226)
    at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
    at javax.faces.component.UICommand.getValue(UICommand.java:218)
    at com.sun.faces.renderkit.html_basic.ButtonRenderer.encodeBegin(ButtonRenderer.java:119)
    at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:864)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1854)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:456)
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:133)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
    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:745)
Caused by: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.mine.projs.library.entity.Employee.empId
    at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:60)
    at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:346)
    at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4746)
    at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:4465)
    at org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:243)
    at org.hibernate.event.internal.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:511)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:116)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
    ... 100 more

这是如何引起的?如何解决?

4 个答案:

答案 0 :(得分:5)

我有同样的问题。这个bug似乎已经从HB 4.3.6开始并且幸存了下来,我正在尝试4.3.10;结果相同。

在我看来,实体的方式是&#39;在HB 4.3.6+中访问的字段已更改,可能与类加载器有关。在HB 4.3.6之前,将数据库驱动程序jar文件嵌入到ear文件中可以正常工作(部署非常简单和干净)。在4.3.6之后,它没有工作(没有找到类的异常),现在驱动程序jar文件必须放在Glassfish的lib文件夹中。

答案 1 :(得分:1)

这来自类加载器问题,当hibernate在部署时加载初始类时,会创建一个虚拟的classLoader来构建目录。当你在运行时,目录中的类没有相同的类加载器,sun.reflect.UnsafeFieldAccessorImpl.ensureObj的方法失败。

protected void ensureObj(Object obj)
{
    if(!field.getDeclaringClass().isAssignableFrom(obj.getClass()))
    {
        throwSetIllegalArgumentException(obj);
    }
}

从DirectPropertyAccessor $ DirectGetter.get(Object)行调用此方法:57

我通过创建一个自定义jpa提供程序来解决glassfish 4.1和hibernate-entitymanager-4.3.11.Final.jar中的问题,该提供程序附加了正确的类加载器。

package org.hibernate.jpa;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;

import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.PersistenceUnitInfo;

import org.hibernate.jpa.HibernatePersistenceProvider;

/**
 * Lazy HibernatePersistenceProvider whose take Thread class loader as source
 * and not the dummy one
 * 
 * @author Alexandre Heroux
 *
 */
public class LazyHibernatePersistenceProvider extends HibernatePersistenceProvider {
    @SuppressWarnings("rawtypes")
    @Override
    public EntityManagerFactory createContainerEntityManagerFactory(final PersistenceUnitInfo info,
            final Map properties) {
        return (EntityManagerFactory) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                new Class[] { EntityManagerFactory.class }, new InvocationHandler() {
                    private EntityManagerFactory entityManagerFactory = null;

                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        return method.invoke(getEntityManagerFactory(info, properties), args);
                    }

                    /**
                     * Create the EntityManagerFactory when is not exists
                     * 
                     * @param info
                     * @param properties
                     * @return
                     */
                    protected EntityManagerFactory getEntityManagerFactory(PersistenceUnitInfo info, Map properties) {
                        if (entityManagerFactory == null) {
                            synchronized (this) {
                                if (entityManagerFactory == null) {
                                    entityManagerFactory = LazyHibernatePersistenceProvider.this
                                            .createParentContainerEntityManagerFactory(info, properties);
                                }
                            }
                        }
                        return entityManagerFactory;
                    }
                });
    }

    /**
     * Call parent method
     * 
     * @param info
     * @param properties
     * @return
     */
    protected EntityManagerFactory createParentContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) {
        return super.createContainerEntityManagerFactory(info, properties);
    }
}

答案 2 :(得分:0)

这可能是Hibernate的一个问题。

  

尝试保留新的&#34;产品&#34;时会引发以下异常。实体(参见测试用例)由Hibernate 4.3.6.FINAL提供。但是,如果我将maven依赖项更改为4.3.5.FINAL而不触及任何其他代码,它的工作完全正常。

来自Hibernate issue tracker

所以我建议将Hibernate的版本改为4.3.5。我遇到了同样的问题并修复了它。

答案 3 :(得分:-3)

您的类应使用类似

的注释将字段映射到表列
@Entity
@Table(name="employee")
public class Employee implements Serializable{
    private static final long serialVersionUID = 3454567L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @cloumn(name="emp_id")
    private int empId;

    @Column(name="user_name")
    private String username;

    public int getEmpId() {
        return empId;
    }

    public void setEmpId(int empId) {
        this.empId = empId;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}