Java – JPA onetomany list cannot find mappedby attribute that should be inherited

We are currently making some requirements. We must add some similar entities (car pictures, pet pictures, holiday pictures...) to the database. These pictures belong to one owner (person) We do not link byte arrays directly, but use references After that, more picture types may be added to keep the complexity low. We want to link them directly to Java classes so that we can use instances and similar things We want to use @ inheritance for the superclass pictureref, which contains common properties and links to this person Then there is another entity, person, which will contain a list of these subclasses This is the onetomany relationship with the mappedby property This mappedbyattribute is unknown, so JPA will return this error to us:

Caused by: org.hibernate.AnnotationException: mappedBy reference an unkNown
target entity property:  de.company.project.somepackages.PictureRef.person 
in de.company.project.somepackages.Person.picturesOfCars

I think it's best to use the following code For ease of reading, I deleted other properties and getters / setters, as well as ID sequences

1) All JPA entries are derived from an abstract entity containing ID and audit value This applies to other subclasses, so I don't think this class will cause problems

Class abstractentity

@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
@Id
// Sequence deFinition removed
private Long id;
// other values are following //
}

2) Then we have a superclass that must contain a common attribute All derived classes must be written in a table (because they look very similar) In addition, we will have business logic that works directly with the entity, for example, load or delete by ID

Class picture reference

@Entity
@Table(name = "t_picture_ref")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "picture_type")
// Sequence DeFinition removed
public class PictureRef extends AbstractEntity {
// common attributes,e.g. name or link to file //

@ManyToOne
@JoinColumn(name = "person_id")
private Person person;
}

3) Then there are at least two subclasses More is coming They will contain attributes related only to such pictures

Carpictureref class

@Entity
@DiscriminatorValue("car")
public class CarPictureRef extends PictureRef {

@Column(name="licence_plate_visible")
private boolean licensePlateVisible;
}

Class holidaypictureref

@Entity
@DiscriminatorValue("holiday")
public class HolidayPictureRef extends PictureRef {

@Column(name="weather_condition")
private String weatherCondition;
}

4) Then there is the person who owns / uploads all these pictures This person has a list of various images because they are handled very differently by the application Each list contains specific subclasses, but for the mappedby attribute, we use the people in the superclass pictureref Maybe this inheritance is impossible?

Class personnel

@Entity
@Table(name = "t_person")
// Sequence DeFinition removed
public class Person extends AbstractEntity {

@OneToMany(mappedBy = "person",targetEntity = CarPictureRef.class)
private List<CarPictureRef> picturesOfCars;

@OneToMany(mappedBy = "person",targetEntity = HolidayPictureRef.class)
private List< HolidayPictureRef> picturesOfHolidays;

// a lot of other fields following //
}

One solution might be to store all attributes in one table (we still want to do it), and then store only one entity pictureref Then we will write application logic on the back end to evaluate the picturetype and create new classes for the corresponding business case But it looks a little ugly - I want a JPA solution for this common use case? Maybe we're just missing one or more comments?

For completeness, I added a full stack trace We are using hibernate 4.3 8. Final and deployed to wildfly 8.2 An error occurred during 0.final

21:19:24,283 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 88) MSC000001: Failed to start service jboss.persistenceunit."Example-1.0-SNAPSHOT.war#ExamplePU": org.jboss.msc.service.StartException in service jboss.persistenceunit."Example-1.0-SNAPSHOT.war#ExamplePU": javax.persistence.PersistenceException: [PersistenceUnit: ExamplePU] Unable to build Hibernate SessionFactory
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:172) [wildfly-jpa-8.2.0.Final.jar:8.2.0.Final]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:117) [wildfly-jpa-8.2.0.Final.jar:8.2.0.Final]
at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.8.0_25]
at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:474) [wildfly-security-manager-1.0.0.Final.jar:1.0.0.Final]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:182) [wildfly-jpa-8.2.0.Final.jar:8.2.0.Final]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_25]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_25]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_25]
at org.jboss.threads.JBossThread.run(JBossThread.java:122) [jboss-threads-2.1.1.Final.jar:2.1.1.Final]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: ExamplePU] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1239) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access$600(EntityManagerFactoryBuilderImpl.java:120) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:855) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:845) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:844) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.jboss.as.jpa.hibernate4.TwoPhaseBootstrapImpl.build(TwoPhaseBootstrapImpl.java:44) [jipijapa-hibernate4-3-1.0.1.Final.jar:]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:154) [wildfly-jpa-8.2.0.Final.jar:8.2.0.Final]
... 8 more
Caused by: org.hibernate.AnnotationException: mappedBy reference an unkNown target entity property:  
de.company.project.somepackages.PictureRef.person in de.company.project.somepackages.Person.picturesOfCars
at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:768) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:728) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:70) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1697) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1426) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:852) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
... 13 more

21:19:24,291 ERROR [org.jboss.as.controller.management-operation] (management-handler-thread - 2) JBAS014613: Operation ("deploy") Failed - address: ([("deployment" => "Example-1.0-SNAPSHOT.war")]) - failure description: {"JBAS014671: Failed services" => {"jboss.persistenceunit.\"Example-1.0-SNAPSHOT.war#ExamplePU\"" => "org.jboss.msc.service.StartException in service jboss.persistenceunit.\"Example-1.0-SNAPSHOT.war#ExamplePU\": javax.persistence.PersistenceException: [PersistenceUnit: ExamplePU] Unable to build Hibernate SessionFactory
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: ExamplePU] Unable to build Hibernate SessionFactory
Caused by: org.hibernate.AnnotationException: mappedBy reference an unkNown target entity property: de.company.project.somepackages.PictureRef.person in de.company.project.somepackages.Person.picturesOfCars"}}
21:19:24,292 ERROR [org.jboss.as.server] (management-handler-thread - 2) JBAS015870: Deploy of deployment "Example-1.0-SNAPSHOT.war" was rolled back with the following failure message: 
{"JBAS014671: Failed services" => {"jboss.persistenceunit.\"Example-1.0-SNAPSHOT.war#ExamplePU\"" => "org.jboss.msc.service.StartException in service jboss.persistenceunit.\"Example-1.0-SNAPSHOT.war#ExamplePU\": javax.persistence.PersistenceException: [PersistenceUnit: ExamplePU] Unable to build Hibernate SessionFactory
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: ExamplePU] Unable to build Hibernate SessionFactory
Caused by: org.hibernate.AnnotationException: mappedBy reference an unkNown target entity property: Caused by: org.hibernate.AnnotationException: mappedBy reference an unkNown target entity property: de.company.project.somepackages.PictureRef.person in de.company.project.somepackages.Person.picturesOfCars"}}

Solution

You have learned more about areas not covered in the JPA specification JPA spec 2.11 stipulates:

Exactly what support is not defined

When you try to map @ onetomony to a subclass that inherits the @ manytoone relationship

public class Person extends AbstractEntity {

    @OneToMany(mappedBy = "person",targetEntity = CarPictureRef.class)
    private List<CarPictureRef> picturesOfCars;

    @OneToMany(mappedBy = "person",targetEntity = HolidayPictureRef.class)
    private List< HolidayPictureRef> picturesOfHolidays;

    ...

}

Hibernate complains

mappedBy reference an unkNown target entity property

Therefore, when mappedby is parsed as a subclass, hibernate does not allow inheritance of fields (in this case, person) However, there is enough information in the relationship definition to solve these relationships, which eclipse link does very well

You can transfer @ manytoone from super (pictureref) to specific subclasses (carpictureref, etc.)

@Entity
public class CarPictureRef extends PictureRef {

    @ManyToOne
    @JoinColumn(name = "person_id")
    private Person person;

    ...

}

With this solution, you can keep the @ onetomany mapping in person Unfortunately, this doesn't work in Hibernate because hibernate will look up people with the correct person_ ID (in this case, any pictureref subclass), and then complain that the type found is the wrong type

org.hibernate.WrongClassException: Object [id=55] was not of the specified subclass.

Similarly, hibernate can solve this problem by using the discriminator column, but this is not the case, and this is what eclipse link does

Your method is to specify a different join column for each subclass, which means that when each new subclass appears, you need to modify the table you think is not ideal

Using hibernate, you can locate the pictureref superclass on the @ onetomany relationship so that the person entity becomes;

@Entity
@Table(name = "t_person")
// Sequence DeFinition removed
public class Person extends AbstractEntity {

    @OneToMany(mappedBy = "person",targetEntity = PictureRef.class)
    private List<PictureRef> pictures;

    ...

}

Then you will have a list of pictureref, which will become any subclass You can test the items in the list and set the transient field that contains each required subtype To this extent, hibernate supports polymorphic Association, but eclipse link has done a lot, so we should pay attention to portability

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>