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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27289632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 04:06:49  来源:igfitidea点击:

Hibernate - @OneToMany - com.sun.jdi.InvocationException occurred invoking method

javahibernateannotations

提问by Arturo

I have a problem with OneToMany relations. I'm using spring-mvc and spring-security and hibernate 4.

我对 OneToMany 关系有疑问。我正在使用 spring-mvc 和 spring-security 以及 hibernate 4。

I'm using annotations for all.

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

My problem is in the entity War when I see the atributte List players debugging, I see players= PersistentBagand when I click it com.sun.jdi.InvocationException occurred invoking method.

当我看到属性列表播放器调试时,我的问题出在实体战争中players= PersistentBag,当我单击它时com.sun.jdi.InvocationException occurred invoking method.

Also I get this Exceptions:

我也得到这个例外:

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

Entities:

实体:

@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

}

My DAO

我的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;
    }

采纳答案by Tkachuk_Evgen

Hibernate documentation says:

休眠文档说:

In the normal case the orders association would be lazy loaded by Hibernate

在正常情况下,Hibernate 会延迟加载订单关联

So, you need to use eager fetching:

因此,您需要使用预先获取:

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

回答by Harshit

Replace My Dao

替换我的道

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

回答by J. Jerez

FetchType.EAGER is not efficient. You must include the org.hibernate.annotations.Fetch annotation.

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

So:

所以:

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

回答by Aarti

In my case it is because I was doing

就我而言,这是因为我在做

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

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

since jpadid not return entity as List<Map<String,Object>>when we select by alias of entity, so we need to do:

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

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

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

after that we can convert list of entity to list of map. or we can also do selectquery as:

之后我们可以将实体列表转换为地图列表。或者我们也可以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);