2016-05-17 8 views
0

Ich habe zwei Klassen:Hibernate @OneToMany und @ManyToOne Beziehung funktioniert falsch

@Entity 
public class Player 
{ 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 

    private String nick; 

    @ManyToOne 
    private Team team; 
} 

und

@Entity 
public class Team 
{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 

    private String name; 

    @OneToMany(mappedBy = "team") 
    private List<Player> players = new ArrayList<>(); 

    @Transient 
    public void addPlayer(Player player) 
    { 
     if (player != null) 
      players.add(player); 
    } 
} 

und in Controller füge ich ein Team und einen Spieler Datenbank

private void addTeams() 
    { 
     Team team = new Team(); 
     team.setName("Name"); 

     Player p = new Player(); 
     team.addPlayer(p); 
     teamsService.addTeam(team); 
     playersService.addPlayer(p); 
    } 

Abstact Dao Klasse:

package eniupage.domain.repository.impl; 

import java.io.Serializable; 
import java.lang.reflect.ParameterizedType; 
import java.util.List; 

import javax.inject.Inject; 

import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.springframework.transaction.annotation.Transactional; 

import eniupage.domain.repository.Dao; 

public abstract class DaoImpl<T> implements Dao<T> 
{ 
    @Inject 
    private SessionFactory sessionFactory; 

    private Class<T> domainClass; 

    protected Session currentSession() 
    { 
     return sessionFactory.getCurrentSession(); 

    } 

    @SuppressWarnings("unchecked") 
    private Class<T> getDomainClass() 
    { 
     if (domainClass == null) 
     { 
      ParameterizedType thisType = (ParameterizedType) getClass().getGenericSuperclass(); 
      this.domainClass = (Class<T>) thisType.getActualTypeArguments()[0]; 
     } 
     return domainClass; 
    } 

    private String getDomainClassName() 
    { 
     return getDomainClass().getName(); 
    } 

    @Transactional 
    public void add(T t) 
    { 
     currentSession().save(t); 
    } 

    @Transactional 
    @SuppressWarnings("unchecked") 
    public List<T> getAll() 
    { 
     return currentSession().createQuery("from " + getDomainClassName()).list(); 
    } 

    @Transactional 
    @SuppressWarnings("unchecked") 
    public T get(Serializable id) 
    { 
     return (T) currentSession().get(getDomainClass(), id); 
    } 

    @Transactional 
    @SuppressWarnings("unchecked") 
    public T load(Serializable id) 
    { 
     return (T) currentSession().load(getDomainClass(), id); 
    } 

    @Transactional 
    public long count() 
    { 
     return (Long) currentSession().createQuery("select count(*) from " + getDomainClassName()).uniqueResult(); 
    } 
} 

Ich habe Config I hibernate.hbm2ddl.auto als create-drop

Im Ergebnis überwintern bekam zwei Tabellen: mit Spalte team_id die null

  • Team-Tabelle
  • Spieler-Tabelle.

Warum ist team_id null? Ich habe team.addPlayer(p)

Antwort

0

müssen Sie die team dieses Players setzen, wie es mappedBy Team Entity war.

public void addPlayer(Player player) 
{ 
    if (player != null) { 
     player.setTeam(this); // here is the change 
     players.add(player); 
    } 
} 

oder Änderung folgenden

Player p = new Player(); 
p.setTeam(team); // here is the change 
team.addPlayer(p); 
+0

das, weil in JPA Welt ist. Sie haben den Eigentümer der Beziehung als "Player" festgelegt, indem Sie das Attribut "mappedBy" festgelegt haben. Ja, ich weiß, es ist genau das Gegenteil definiert als mit relationalem Mapping. – gmaslowski

+0

Ich habe nichts 'mappedBy' eingestellt. OP tat, aber er stellt nicht die Eltern von 'Player' durch einen' team' –

+0

Einstellung I Tutorial sah, wo somebode EntityMenager.persist verwendet() anstelle von Session.save(), und es funktioniert meine Art und Weise. Hmm .. – Bambelal

0

Wenn eine bidirektionale Beziehung haben, dann müssen Sie immer beide Enden der Beziehung gesetzt.

private void addTeams() 
     { 
      Team team = new Team(); 
      team.setName("Name"); 

      Player p = new Player(); 
      p.setTeam(team); 
      team.addPlayer(p); 
      teamsService.addTeam(team); 
      playersService.addPlayer(p); 
     } 

Außerdem müssen Sie Cascade Type im Mapping angeben.

@OneToMany(mappedBy = "team",cascade = CascadeType.PERSIST) 
private List<Player> players = new ArrayList<>(); 
+0

Im Tutorial ich oben verknüpft niemand beide Enden der Beziehung verwenden. – Bambelal

0

Menschen in Tutorien nie beide Ende der Beziehung gesetzt und ihr Code funktioniert (zum Beispiel https://www.youtube.com/watch?v=jAi8bY-H_ek) :)

Wenn ich player.setTeam(team) anstelle von team.addPlayer(player) es funktioniert (Spalte nicht NULL). der Besitzer der Beziehung zum Einstellen des Kartierschlüssel verantwortlich ist.

Verwandte Themen