Ich habe ein Problem mit den Beziehungen von 3 Entitäten. Ich habe versucht, eine Vererbung heriarchy zu haben, aber innerhalb der Kindklasse verweise ich auf eine Liste meiner Elternklassenobjekte als Attribut. Daher möchte ich, dass meine untergeordnete Klassen-Entity eine Mapper-Tabelle ist, in der die Zuordnung zwischen ihr und ihrem übergeordneten Element angezeigt wird. Dabei stieß ich auf eine Reihe von Beziehungsproblemen Ich habe ein Beispielprojekt erstellt, das die Funktionalität emuliert.SpringBoot + Hibernate Beziehungsprobleme
Automobile.java
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.OneToOne;
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class Automobile implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long Id;
@OneToOne
private Manufacturer manufacturer;
@OneToOne
private AutomobileType autotype;
@OneToOne
private LoanerCar loanerCarID;
private String vin;
//Getters and Setters, Arg Constructors, No-Arg Constructor, toString
}
LoanerCar.java
package com.example.demo.domains;
import java.sql.Timestamp;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
@Entity
public class LoanerCar extends Automobile{
private static final long serialVersionUID = 1L;
private String name;
private Timestamp dateLoaned;
private Timestamp dateReceived;
@OneToMany
private List<Automobile> alist;
//Getters and Setters, Arg Constructors, No-Arg Constructor, toString
}
TotaledCar.java
import java.util.List;
import javax.persistence.Entity;
@Entity
public class TotaledCar extends Automobile {
private static final long serialVersionUID = 1L;
private List<LoanerCar> eligibleLoaners;
// Getter ein nd Setters, Arg Konstruktoren, No-Arg-Konstruktor, toString }
AutomobileBaseRepository.java
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;
import com.example.demo.domains.Automobile;
import com.example.demo.domains.Manufacturer;
@NoRepositoryBean
public interface AutomobileBaseRepository<T extends Automobile> extends JpaRepository<T, Long> {
List<T> findByLoanerCarID(Long id);
List<T> findByVinAndManufacturerAndLoanerCarID(String vin, Manufacturer manfacturer, Long id);
}
Automobile, TotaledCar, LoanerCar Repositories erweitern die AutomobileBaseRespoistory und hat keine Methoden.
LoaanerController.java
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.domains.LoanerCar;
import com.example.demo.domains.Manufacturer;
import com.example.demo.domains.TotaledCar;
import com.example.demo.repositories.LoanerCarRepository;
import com.example.demo.repositories.ManufacturerRepository;
import com.example.demo.repositories.TotaledCarRepository;
@RestController
public class LoanerController {
@Autowired
LoanerCarRepository loanerRepo;
@Autowired
TotaledCarRepository totaledCarRepo;
@Autowired
ManufacturerRepository manRepo;
@RequestMapping(value="/loaner/all", method = RequestMethod.GET)
public List<LoanerCar> loaners(){
List<LoanerCar> list = loanerRepo.findAll();
return list;
}
@RequestMapping(value="/loaner/{id}", method=RequestMethod.GET)
public LoanerCar getLoaner(@PathVariable Long id){
LoanerCar loanerCar= loanerRepo.findOne(id);
return loanerCar;
}
@RequestMapping(value="/loaner", method=RequestMethod.GET)
public String response(@RequestParam("vin") String vin, @RequestParam("manufacturer") Long manfuacturerId, @RequestParam("loanerId") Long loanerId){
Manufacturer manObj = manRepo.findById(manfuacturerId);
List<LoanerCar> loanerList = loanerRepo.findByLoanerCarID(loanerId);
List<TotaledCar> tlist = totaledCarRepo.findByVinAndManufacturerAndLoanerCarID(vin, manObj, loanerId);
for (TotaledCar junk : tlist){
loanerList.addAll(junk.getEligibleLoaners());
}
String strlist = loanerList.toString();
return strlist;
}
}
So ist der Fluss dieser Abbildung von sein annehmen, wenn ich hinzufügen, ein Automobil wird eine loanerId von null hat standardmäßig. Und wenn ich der loanerId einen Wert zuweise, wird dieser der LoanerCar-Tabelle zugeordnet, in der eine AutomobileId von der Elternklasse/-tabelle und eine loanerId in der LoanerCar-Klasse/-Tabelle enthalten sind. In der LoanerCar-Tabelle ist die loanerId also an eine Liste von Automobilen gebunden, die für LoanerCars in Frage kommen. So hat Automobile einen loanerId, und dieser loanerId kann viele Autos. Und meine Steuerungsmethode wird mir nur eine Liste sowohl der Summe als auch der Leihwagen bekommen. Ich weiß, es klingt verwirrend, aber ich verstehe, dass ich versuche, das zu erreichen.
Stack Trace
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081) ~[spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856) ~[spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at com.example.demo.SpringJpaInheritanceRelationshipsApplication.main(SpringJpaInheritanceRelationshipsApplication.java:10) [classes/:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:954) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:882) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353) ~[spring-orm-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:370) ~[spring-orm-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:359) ~[spring-orm-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE]
... 16 common frames omitted
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.List, at table: totaled_car, for columns: [org.hibernate.mapping.Column(eligible_loaners)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:431) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:398) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.mapping.Property.isValid(Property.java:225) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:595) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.mapping.JoinedSubclass.validate(JoinedSubclass.java:44) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:443) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
... 22 common frames omitted
Als Randbemerkung, haben Sie versucht, feder Daten anstelle von Hibernate, da Sie bereits Frühling Bibliothek verwenden? – jalv1039
Ja, ich benutze Frühjahr Daten jpa, durch die Verwendung von Repositories. Kannst du genauer sein. Ich glaube, dass die Federdaten auch die Beziehungsanmerkungen haben. Aber ich bin verwirrt, wo ich sie hinstellen soll. die Aufgabe zur Hand gegeben. – user3116769