2016-05-17 76 views
0

我有兩個類:休眠@OneToMany和@ManyToOne關係工作的錯誤

@Entity 
public class Player 
{ 

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

    private String nick; 

    @ManyToOne 
    private Team team; 
} 

@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); 
    } 
} 

和控制器我添加一個團隊,一個球員的數據庫

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 class:

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(); 
    } 
} 

我加入冬眠配置hibernate.hbm2ddl.autocreate-drop

在結果我得到了兩個表:

  • 團隊表列TEAM_ID是空
  • 球員表。

爲什麼team_id爲空?我做team.addPlayer(p)

回答

0

你必須設置該玩家的team,因爲它是mappedBy隊的實體。

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

或更改以下

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

這是因爲在JPA世界中,關係的所有者負責設置映射關鍵字。通過設置'''''''''''''''''''''''''''你可以通過設置''''''''''''''屬性來指定關係的所有者爲玩家是的,我知道,它的定義與關係映射完全相反。 – gmaslowski

+0

我沒有設置任何'mappedBy'。 OP沒有,但他沒有通過設置一個「團隊」來設置「Player」的父親 –

+0

我看到了教程,其中somebode使用了EntityMenager.persist()而不是Session.save(),並且按照我的方式工作。嗯.. – Bambelal

0

如果有一個雙向的關係,那麼你必須設置關係的兩端。

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); 
     } 

此外,您必須在映射中提供級聯類型。

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

在教程中,我沒有使用關係的兩端。 – Bambelal