2016-12-28 5 views
1

Ich habe eine zu viele Beziehung zwischen Personenklasse und Auto-Klasse. Eine Person kann viele Autos besitzen und umgekehrt. Ich verwende eine restliche API, um Daten zu posten. Meine Anmerkungen und Get-Service funktioniert gut, aber mein Post-Dienst löst "java.sql.SQLIntegrityConstraintViolationException: ORA-01400: kann NULL nicht einfügen" -Fehler, wenn ich versuche, neue Daten einzufügen. Der Fremdschlüssel der untergeordneten Tabelle wird als Null eingefügt.Hibernate save Objekt (eine zu viele Beziehung) Fremdschlüssel ist Null

Hier ist ein Teil meines Codes.

Person.java

private List<Car> cars = new ArrayList<Car>(); 

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="person")  
@JsonManagedReference 
public List<Car> getCars() { 
    return cars; 
} 

Car.java

private Person person; 

    @ManyToOne 
    @JoinColumn(name = "PERSON_ID", nullable = false, updatable = true, insertable = true) 
    @JsonBackReference 
    public Person getPerson() { 
     return person; 
    } 

Mein Serviceklasse:

@POST 
     @Path("/PersonRegistration") 
     @Consumes(MediaType.APPLICATION_JSON) 
     public Response postPersonCars(Person person) throws Exception{ 

      Session session = null;  
      ObjectMapper mapper = new ObjectMapper(); 
      //Person per = new Person(); 
      //Car cars = new Car(); 
      try{ 
       session = HibernateUtil.getSessionFactory().openSession(); 
       session.beginTransaction(); 
       //per.setCars(person.getCars()); 
       session.save(person); 
       session.getTransaction().commit(); 

      }catch(Exception e){ 
       e.printStackTrace(); 
       throw e; 
      }finally{ 
       if(null != session){ 
        session.close(); 
       } 
      } 

      return Response.status(201).entity(mapper.writeValueAsString(person)).build(); 
     } 

Antwort

3

Diese Anmerkung:

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="person") 

hat zwei Konsequenzen:

  1. mappedBy impliziert, dass Car die besitzende Seite der Beziehung ist. Wenn Sie also eine Beziehung zwischen Car und Person, herstellen möchten, müssen Sie dies tun, indem Sie die Eigenschaft Car.person auf den entsprechenden Wert setzen. Änderungen an Person.cars werden von Hibernate ignoriert.
  2. cascade=CascadeType.ALL bedeutet, dass, wenn Sie eine Person speichern, Hibernate wird auch der Betrieb auf allen in Person.cars

Ergebnis enthaltenen Entitäten speichern aufrufen: Sie Session.save() auf eine Reihe von Car Einheiten fordern, die nicht über die Car.person Eigenschaft richtig eingestellt.

Lösung: entweder die Eigentümer Seite der Beziehung ändern (beachten Sie, dass Sie auch ein @JoinColumn auf Person.cars benötigen, wenn Sie nicht über eine zusätzliche Datenbanktabelle erstellt werden soll), um die Car.person Eigenschaft oder Schleife durch Person.cars und richtig eingestellt in jeder von ihnen.

cascade=CascadeType.ALL schlägt vor, dass die erste Lösung besser zu Ihrem Anwendungsfall passt.

+0

Danke crizis für Ihre Antwort. Ich rufe session.save auf Person Entity, die ArrayList von Autos hat. Also sollte ich den JSON iterieren und Autos zu Person setzen? – offeron

+0

Sie sollten über 'person.getCars()' iterieren und 'car.setPerson (person) 'auf jedem' Auto 'anrufen. – crizzis

+0

Also zum Löschen muss ich das gleiche tun? iterieren über person.getCars und löschen Auto und dann Person? Ist das ein guter Ansatz oder fehlt mir etwas? – offeron

Verwandte Themen