简体   繁体   中英

JPA-Hibernate - “could not get a field value by reflection getter of with inheritance

I have an entity that is base class for some entities.

@Entity
@Table(name = "resource")
@Inheritance(strategy = InheritanceType.JOINED)
public class Resource implements Serializable{

}

I have some sub classes that extends from Resource .

@Entity
@Table(name = "ResourceWithA")
@PrimaryKeyJoinColumn(name = "ResourceWithA_id")
public class ResourceWithA extends Resource implements Serializable, AInterface{

    @Column
    private boolean inService;
    @Override
    public void setInService(boolean inService) {
        this.inService = inService;
    }

    @Override
    public boolean getInService() {
       return inService;
    }

}

@Entity
@Table(name = "ResourceWithB")
@PrimaryKeyJoinColumn(name = "ResourceWithB_id")
public class ResourceWithB extends ResourceWithA implements Serializable{

}

When I want to insert data , I am getting folowing exceptions. I am not getting this exception for only inService attribute.Class has some other attributes like Collection, they have also problematic

javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.ResourceWithB.inService
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1214)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1147)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1153)
at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:695)
at com.test.persistence.ConnectionTest.saveData(ConnectionTest.java:44)
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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.ResourceWithB.inService
at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:62)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getPropertyValues(AbstractEntityTuplizer.java:485)
at org.hibernate.tuple.entity.PojoEntityTuplizer.getPropertyValues(PojoEntityTuplizer.java:243)
at org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValues(AbstractEntityPersister.java:3834)
at org.hibernate.event.def.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:600)
at org.hibernate.event.def.DefaultMergeEventListener.mergeTransientEntity(DefaultMergeEventListener.java:337)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:303)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:258)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:869)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:851)
at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:279)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:425)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:362)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:338)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:476)
at org.hibernate.event.def.DefaultMergeEventListener.mergeTransientEntity(DefaultMergeEventListener.java:388)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:303)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:258)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:84)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:859)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:843)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:847)
at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:686)
... 24 more
Caused by: java.lang.IllegalArgumentException: Can not set boolean field com.ResourceWithA.inService to com.Resource
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)
at sun.reflect.UnsafeBooleanFieldAccessorImpl.getBoolean(UnsafeBooleanFieldAccessorImpl.java:22)
at sun.reflect.UnsafeBooleanFieldAccessorImpl.get(UnsafeBooleanFieldAccessorImpl.java:18)
at java.lang.reflect.Field.get(Field.java:358)
at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:59)
... 51 more

EDITTED: setter and getter methods. As I said this problem is not related to only inService field. If I annotate it as @Transient , same exception is thrown for other fields.

public interface AInterface {
    public void setInService(boolean inService);

    public boolean getInService();
}

EDITED : I noticed this case. I have a container class that stores a list of Resources. There are some cascade definitions,

public class Container{
@Id
@GeneratedValue
@Column(name = "container_id")
private long id; // unique identifier
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "container_resources", joinColumns = {
    @JoinColumn(name = "container_id", referencedColumnName = "container_id")
}, inverseJoinColumns = {
    @JoinColumn(name = "id", referencedColumnName = "id")
})
/** list of resources inside power system. */
private Collection<Resource> resources = new HashSet<Resource>();

}

I am doing save operation over Container. em.merge(container).

If there is one type of resource inside resources , no problem exists. If I have multiple resource types, them I am getting setting/getting reflection errors.

You can annotate the ResourceWithA with inheritance

@Entity
@Table(name = "ResourceWithA")
@PrimaryKeyJoinColumn(name = "ResourceWithA_id")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class ResourceWithA extends Resource implements Serializable, AInterface{

As I mentioned in problem description, I was using em.merge. When I use persist, the problem is solved.But I do not know what is the real reason behind solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM