2017-06-08 4 views
1

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 
+0

Als Randbemerkung, haben Sie versucht, feder Daten anstelle von Hibernate, da Sie bereits Frühling Bibliothek verwenden? – jalv1039

+0

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

Antwort

0

Sie verwenden Feldzugriffsstrategie (bestimmt durch @Id Anmerkung). Setzen Sie jeden möglichen PPV im Zusammenhang Anmerkung rechts oben

private List<LoanerCar> eligibleLoaners; 

siehe here

+0

Vielen Dank, das hat funktioniert, ich habe eine Nebenfrage was, wenn ich die ID der Automobilklasse und ein Feld aus der LoanerCar-Klasse als zusammengesetzten Schlüssel verwenden wollte, habe ich über forcedDiscrimnator gelesen, aber ich kann die Abhängigkeit nicht finden um es zu benutzen. Außerdem werden die List-Elemente als separate Tabelle erstellt. Ist es möglich, diese Daten in der entsprechenden Tabelle zu speichern? – user3116769

+0

NP. Ich denke, du solltest es als eine neue Frage stellen.By the way, markieren Sie bitte diese Antwort als akzeptiert. –

+0

Np danke nochmal – user3116769