我拥有类CreatureType和Weapon(对付某些生物的最佳武器),我需要模拟武器对特定CreatureType有不同效率的事实。所以我创建了具有效率属性的关联实体CreatureTypeWeapon。具有属性的关联实体的DAO类 - 如何实现它?
我编写它以这种方式(其原理是一样的)http://uaihebert.com/?p=1674&page=22
为什么我问这个问题的原因是,我不知道如何实现DAO类的关联实体。
我有CreatureType的DAO类,我有用于实现与CRUD操作接口的Weapon的DAO类。
但我在某种程度上错过了处理关联实体的CRUD操作的方法。比方说,我有这样的DAO
public class CreatureTypeWeaponDAOImpl implements CreatureTypeWeaponDAO {
@Override
public void create(CreatureTypeWeapon creatureTypeWeapon) {
// implementation
}
// ... other CRUD methods
}
我用这样的:
// this is like a person
CreatureType creatureType = new CreatureType();
creatureType.setName("alien");
creatureType.setMaxHitPoints(200);
// this is like a dog
Weapon weapon = new Weapon();
weapon.setName("ak-47");
// this is like PersonDog
CreatureTypeWeapon creatureTypeWeapon = new CreatureTypeWeapon();
creatureTypeWeapon.setWeapon(weapon);
creatureTypeWeapon.setCreatureType(creatureType);
// this is like "adoptionDate" in the link posted
// 0.5 means when I hit it with ak-47 it takes half of its max hit points
// so I have to fire 2 times on it and it will die.
creatureTypeWeapon.setEfficiency(0.5);
// this is actually injected
CreatureTypeWeaponDAO dao = new CreatureTypeWeaponDAOImpl();
dao.create(creatureTypeWeapon);
但问题是,如何实现呢?我能够正常地坚持它,但是我们要说,我要去掉这种关系:
dao.remove(creatureTypeWeapon);
哪位能像这样
public class CreatureTypeWeaponDAOImpl implements CreatureTypeWeaponDAO {
void remove(CreatureTypeWeapon arg) {
CreatureTypeWeapon toRemove = em.find(/* WHAT TO PUT HERE */);
em.remove(toRemove);
}
}
正常情况下可以实现,我把那里
em.find(CreatureTypeWeapon.class, arg.getId());
但在关联实体中没有“id”...
UPDATE
好了,所以这是我如何在CreatureTypeWeaponDAOImpl
TypedQuery<CreatureTypeWeapon> query =
em.createQuery(
"SELECT ctw FROM CreatureTypeWeapon ctw WHERE "
+ "creatureType = :creatureType "
+ "AND "
+ "weapon = :weapon",
CreatureTypeWeapon.class);
CreatureType creatureTypePersisted =
em.getReference(CreatureType.class, creatureType.getId());
Weapon weaponPersisted = em.getReference(Weapon.class, weapon.getId());
query.setParameter("creatureType", creatureTypePersisted);
query.setParameter("weapon", weaponPersisted);
return query.getSingleResult();
获取得到一个CreatureTypeWeapon实例的方式似乎是确定,但是当我要在remove方法简单,只需将其删除em.remove(creatureTypeWeapon); (如建议)我得到这个错误:
javax.persistence.NoResultException: No entity found for query at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:291)
at cz.muni.fi.pa165.creatures.dao.impl.CreatureTypeWeaponDAOImpl.get(CreatureTypeWeaponDAOImpl.java:101)
这是一种方法,我怎么正在测试它:
public void testRemoveCreatureTypeWeapon() {
Weapon w = new Weapon("ak-47");
weaponDAO.create(w);
CreatureType ct = new CreatureType("alien", 200);
creatureTypeDAO.create(ct);
assertNotNull(weaponDAO.get(w.getId()));
assertNotNull(creatureTypeDAO.get(ct.getId()));
CreatureTypeWeapon ctw = new CreatureTypeWeapon();
ctw.setCreatureType(ct);
ctw.setWeapon(w);
ctw.setEffectivity(new Float(0.5));
creatureTypeWeaponDAO.create(ctw);
CreatureTypeWeapon ctw2 =
creatureTypeWeaponDAO.get(ctw.getCreatureType(), ctw.getWeapon());
ctw2.setCreatureType(ctw.getCreatureType());
ctw2.setWeapon(ctw.getWeapon());
creatureTypeWeaponDAO.remove(ctw);
assertNull(creatureTypeWeaponDAO.get(ctw2.getCreatureType(), ctw2.getWeapon()));
}
更新#2
好,我知道了,究其原因有这样的错误是,当query.getSingleResult()抛出NoResultException时,这意味着当我试图在删除它的测试后得到实体时,没有这样的记录,所以该方法抛出一个错误,这是很好的。我处理这样的:
try {
return query.getSingleResult();
} catch(NoResultException ex) {
return null;
}
这样做之后,就可以正常删除它,(这是可行的,甚至之前,但我很困惑,认为错误在那里)。
请参阅更新 – stewenson