我遇到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;
}
答案 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);