Hibernate - @OneToMany - com.sun.jdi.InvocationException发生了调用方法

时间:2014-12-04 08:46:23

标签: java hibernate annotations

我遇到OneToMany关系问题。 我正在使用spring-mvc和spring-security以及hibernate 4.

我正在为所有人使用注释。

我的问题是在实体战争中,当我看到atributte List播放器调试时,我看到players= PersistentBag,当我点击它时com.sun.jdi.InvocationException occurred invoking method.

我也得到了这个例外:

org.apache.jasper.JasperException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: clanwar.model.War.players, could not initialize proxy - no Session

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: clanwar.model.War.players, could not initialize proxy - no Session

实体:

@Entity
@Table(name = "WARS")
public class War implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID", nullable = false)
    private int id;

    @ManyToOne
    @JoinColumn(name = "CLAN")
    private Clan clan;

    @Column(name = "START_DATE")
    private Date startDate;

    @Column(name = "ENEMY_NAME")
    private String enemyName;

    @OneToMany(mappedBy = "war")
    private List<WarPlayer> players;

    @Transient
    private List<Enemy> enemies;

    public War() { }

    // Getters and setters.

}

-

@Entity
@Table(name = "WAR_PLAYERS")
public class WarPlayer implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @ManyToOne
    @JoinColumn(name = "WAR")
    private War war;

    @Id
    @ManyToOne
    @JoinColumn(name = "PLAYER")
    private Player player;

    @Column(name = "WAR_NUMBER")
    private int warNumber;

    @ManyToOne
    @JoinColumn(name = "OBJETIVE_1")
    private Attack objetive1;

    @ManyToOne
    @JoinColumn(name = "OBJETIVE_2")
    private Attack objetive2;

    @ManyToOne
    @JoinColumn(name = "RECOMMENDED_1")
    private Attack recommended1;

    @ManyToOne
    @JoinColumn(name = "RECOMMENDED_2")
    private Attack recommended2;

    @ManyToOne
    @JoinColumn(name = "FINAL_1")
    private Attack final1;

    @ManyToOne
    @JoinColumn(name = "FINAL_2")
    private Attack final2;
    private String comment;

    public WarPlayer() {}

    // Getters and setters

}

我的DAO

@Override
    public War findById(int id) throws DaoException {

        War war;

        try {
            war = (War) getSession()
                    .createQuery("from War where ID = :id")
                    .setParameter("id", id)
                    .uniqueResult();
        } catch (Exception e) {
            throw new DaoException(e.getMessage());
        }

        return war;
    }

4 个答案:

答案 0 :(得分:16)

Hibernate文档说:

  

在正常情况下,订单关联将延迟加载   冬眠

所以,你需要使用渴望的提取:

 @OneToMany(mappedBy = "war",fetch = FetchType.EAGER)
 private List<WarPlayer> players;

答案 1 :(得分:2)

FetchType.EAGER效率不高。您必须包含org.hibernate.annotations.Fetch注释。

所以:

@Fetch(FetchMode.SUBSELECT)
@OneToMany(mappedBy = "war", fetch = FetchType.LAZY)
private List<WarPlayer> players;

答案 2 :(得分:0)

替换我的道

@Override
public War findById(int id) throws DaoException {

    Transaction transaction = null;
    Session session = null;

    try {
        session = sessionFactory.openSession();
        session.setFlushMode(FlushMode.COMMIT);
        transaction = session.beginTransaction();

        String hql = "from War where ID = :id";
        Query query = session.createQuery(hql);

                query.setParameter("id", id).uniqueResult();

    } catch (Exception e) {
        throw new DaoException(e.getMessage());
    }

    return war;
}

答案 3 :(得分:0)

我的情况是因为我在做

@Query("SELECT amg FROM AgentmasterGroup amg WHERE amg.merchantmaster.id=:merchantId")

List<Map<String,Object>> findAgentmasterGroupByMerchantId(@Param("merchantId") Integer merchantId);

因为当我们通过实体的别名进行选择时,jpa并没有将实体返回为List<Map<String,Object>>,所以我们需要这样做:

@Query("SELECT amg FROM AgentmasterGroup amg WHERE amg.merchantmaster.id=:merchantId")

List<AgentmasterGroup> findAgentmasterGroupByMerchantId(@Param("merchantId") Integer merchantId);

之后,我们可以将实体列表转换为地图列表。 或者我们也可以通过以下方式进行select查询:

@Query("SELECT amg.id as id, amg.name as name  FROM AgentmasterGroup amg WHERE amg.merchantmaster.id=:merchantId")

List<Map<String,Object>> findAgentmasterGroupByMerchantId(@Param("merchantId") Integer merchantId);