休眠查询不返回正确的结果
Posted
技术标签:
【中文标题】休眠查询不返回正确的结果【英文标题】:Hibernate query not return the correct results 【发布时间】:2015-03-12 17:40:16 【问题描述】:我正在开发一个带有 hibernate 和 spring 的网络应用程序。我正在为所有配置使用注释。
我的问题是试图选择一个带有两个外键的表。
包含所有的实体是:
@Entity
@Table(name = "WAR_PLAYERS_ATTACKS")
public class WarPlayerAttack implements Serializable
private static final long serialVersionUID = 1L;
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "WAR_PLAYER")
private WarPlayer warPlayer;
@Id
@ManyToOne
@JoinColumn(name = "ATTACK")
private Attack attack;
@ManyToOne
@JoinColumn(name = "TYPE_ATTACK")
private TypeAttack typeAttackInWar;
public WarPlayerAttack()
// getters and setters
实体战争玩家:
@Entity
@Table(name = "WAR_PLAYERS")
public class WarPlayer implements Serializable
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID", nullable = false)
private int id;
@ManyToOne
@JoinColumn(name = "WAR")
private War war;
@ManyToOne
@JoinColumn(name = "PLAYER")
private Player player;
@Column(name = "WAR_NUMBER")
private int warNumber;
@Column(name = "HAVE_KING")
private boolean haveKing;
@Column(name = "HAVE_QUEEN")
private boolean haveQueen;
@Column(name = "HAVE_POTIONS")
private boolean havePotions;
@OneToMany(mappedBy = "warPlayer", fetch = FetchType.EAGER)
private List<WarPlayerAttack> attacks;
public List<WarPlayerAttack> getAttacks()
return attacks;
public void setAttacks(List<WarPlayerAttack> attacks)
this.attacks = attacks;
private String comment;
public WarPlayer()
我的 DAO
@Override
public List<WarPlayerAttack> findByIdEnemyAndIdWar(int idEnemy, int idWar) throws DaoException
List<WarPlayerAttack> attackss = null;
List attacks;
try
attackss = getSession()
.createQuery("from WarPlayerAttack wpa where wpa.attack.enemy.id in :idEnemy and wpa.attack.enemy.war.id in :idWar")
.setParameter("idEnemy", idEnemy)
.setParameter("idWar", idWar)
//.createSQLQuery("select * from WAR_PLAYERS_ATTACKS where ATTACK in (select ID from ATTACKS where ENEMY in (select ID from WAR_ENEMIES where ID = ? and WAR = ?))")
//.setParameter(0, idEnemy)
//.setParameter(1, idWar)
.list();
catch (Exception e)
throw new DaoException(e.getMessage());
return attackss;
我的问题是休眠不收集warPlayer
。只收集Attack
和TypeAttack
。
以 JSON 格式收集的数据示例(出现攻击但未显示 warPlayer):
[
"attack":"id":15,"enemy":"id":10,"diffculty":0,"warNumber":2,"stars":1,"strategy":"id":1,"value":"Air","timeRange":"id":1,"value":"6H","typeAttackInWar":"id":3,"value":"Final 1",
"attack":"id":16,"enemy":"id":10,"diffculty":0,"warNumber":2,"stars":2,"strategy":"id":2,"value":"Ground","timeRange":"id":3,"value":"18H","typeAttackInWar":"id":4,"value":"Final 2"
]
如果我使用 SQL,dao 会返回 Object[]
,例如 [[1,1,1],[1,2,1]]
更多信息的表格:
CREATE TABLE WAR_ENEMIES (
ID INT AUTO_INCREMENT NOT NULL,
WAR INT NOT NULL,
WAR_NUMBER INT(2) NOT NULL,
DIFFCULTY INT(1),
CONSTRAINT PK_ENEMY PRIMARY KEY (ID),
CONSTRAINT FK_ENEMY_WAR FOREIGN KEY (WAR) REFERENCES WARS(ID)
);
CREATE TABLE ATTACKS (
ID INT AUTO_INCREMENT NOT NULL,
ENEMY INT,
STARS INT(1) DEFAULT 0,
STRATEGY INT,
TIME_RANGE INT,
CONSTRAINT PK_ATTACK PRIMARY KEY (ID),
CONSTRAINT FK_ATTACK_ENEMY FOREIGN KEY (ENEMY) REFERENCES WAR_ENEMIES(ID),
CONSTRAINT FK_ATTACK_STRATEGY FOREIGN KEY (STRATEGY) REFERENCES STRATEGIES(ID),
CONSTRAINT FK_ATTACK_TIME_RANGE FOREIGN KEY (TIME_RANGE) REFERENCES TIMES_RANGES(ID)
);
CREATE TABLE WAR_PLAYERS (
ID INT NOT NULL AUTO_INCREMENT,
WAR INT NOT NULL,
PLAYER INT NOT NULL,
WAR_NUMBER INT(2) NOT NULL,
HAVE_KING TINYINT(1) NOT NULL DEFAULT 1,
HAVE_QUEEN TINYINT(1) NOT NULL DEFAULT 1,
HAVE_POTIONS TINYINT(1) NOT NULL DEFAULT 1,
COMMENT VARCHAR(2500),
CONSTRAINT PK_PLAYER_IN_WAR PRIMARY KEY (ID),
CONSTRAINT FK_PLAYER_IN_WAR FOREIGN KEY (WAR) REFERENCES WARS(ID),
CONSTRAINT FK_PLAYER_IN_WAR_PLAYER FOREIGN KEY (PLAYER) REFERENCES PLAYERS(ID)
);
CREATE TABLE WAR_PLAYERS_ATTACKS (
WAR_PLAYER INT NOT NULL,
ATTACK INT NOT NULL,
TYPE_ATTACK INT NOT NULL,
CONSTRAINT PK_WAR_PLAYER_ATTACK PRIMARY KEY (WAR_PLAYER, ATTACK),
CONSTRAINT FK_WAR_PLAYER_ATTACK_WAR_PLAYER
FOREIGN KEY (WAR_PLAYER) REFERENCES WAR_PLAYERS(ID),
CONSTRAINT FK_WAR_PLAYER_ATTACK_ATTACK
FOREIGN KEY (ATTACK) REFERENCES ATTACKS(ID),
CONSTRAINT FK_WAR_PLAYER_ATTACK_TYPE
FOREIGN KEY (TYPE_ATTACK) REFERENCES TYPE_ATTACK(ID)
);
我不知道我做错了什么。 (我没有太多时间使用休眠)
在此先致谢并致以最诚挚的问候。
【问题讨论】:
您能否澄清一下,因为目前还不清楚您要问什么。需要注意的一件事是您的warPlayer
被标记为懒惰。
@M.Deinum 我编辑将warPlayer放在warPlayerAttack之后。
你看过我的评论了吗? -> 。需要注意的一件事是您的 warPlayer
被标记为惰性。
@M.Deinum 我也试着在这里澄清这个问题。我有一个带有 warPlayers 和 warEnemies 的场景(战争)。 warPlayer 可以对 WarEnemy 进行攻击。我想收集对特定战争敌人的攻击。
@M.Deinum 抱歉,我理解不好。如果我删除 LAZY,我会得到一个 ***Exception
【参考方案1】:
我在使用 EclipseLink 实现时遇到了类似的问题,我只是简单地解决了 prder 中的 callink .size() 方法来初始化惰性收集。见How to load lazy fetched items from Hibernate/JPA in my controller
【讨论】:
我试图按照你的要求做,但是调用 .size() 或 Hibernate.initialize(),我得到了相同的结果,你能用我的代码举个例子吗?我觉得我做错了什么。 您是否尝试过 EAGER FetcType 而不是 LAZY? 是的,我也得到了 ***Exception 在你的 DAO 中调用.list()
后尝试将 attacks.size()
放入
我这样做了,我得到了相同的结果。我也尝试使用 Hibernate.initialize() 并得到相同的结果。可能会失败,因为warPlayer类有这个? @OneToMany(mappedBy = "warPlayer", fetch = FetchType.EAGER) private List<WarPlayerAttack> attacks;
以上是关于休眠查询不返回正确的结果的主要内容,如果未能解决你的问题,请参考以下文章