Hibernate @OneToMany和@ManyToOne关系错误

时间:2016-05-17 18:22:11

标签: java spring hibernate

我有两个班级:

@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班:

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 config hibernate.hbm2ddl.auto添加为create-drop

结果我得到了两张桌子:

  • 团队表
  • 具有列team_id的播放器表,该列为空。

为什么team_id为空?我做了team.addPlayer(p)

3 个答案:

答案 0 :(得分: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);

答案 1 :(得分: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<>();

答案 2 :(得分:0)

教程中的人从不设置关系的两端,他们的代码工作正常(例如https://www.youtube.com/watch?v=jAi8bY-H_ek):)

当我使用player.setTeam(team)代替team.addPlayer(player)时,它可以正常工作(列不是空的)..