我有类CreatureType和Weapon(对某些生物使用的最佳武器),我需要模拟武器对特定CreatureType具有各种效率的事实。所以我创建了具有效率属性的关联实体CreatureTypeWeapon。
我用这种方式编码(原理是相同的)http://uaihebert.com/?p=1674&page=22
我问这个问题的原因是我不知道如何为关联实体实现dao类。
我有用于CreatureType的DAO类,我有武器的DAO类,它实现了与CRUD操作的接口。
但我在某种程度上错过了处理关联实体上的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”....
更新
好的,这就是我在CreatureTypeWeaponDAOImpl中获取CreatureTypeWeapon实例的方式
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();
似乎没问题,但是当我要在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时,这意味着当我尝试在测试中删除实体后获取实体时,没有这样的记录,所以抛出一个execption,这很好。我像这样处理它:
try {
return query.getSingleResult();
} catch(NoResultException ex) {
return null;
}
这样做之后,可以正常删除它(它甚至可以在它之前实现,但我很困惑并且认为错误存在)。
答案 0 :(得分:0)
你能不能删除CreatureTypeWeapon
实体?我认为您不需要执行查找,只需删除CreatureTypeWeapon
实体即可删除与CreatureType
和Weapon
的关联。
public class CreatureTypeWeaponDAOImpl implements CreatureTypeWeaponDAO {
void remove(CreatureTypeWeapon arg) {
/*Some init codes here*/
session.delete(arg);
}
}
答案 1 :(得分:0)
您需要定义一个新表,该表是表CreatureType
和Weapon
的连接。例如:
@Entity
public class CreatureTypeWeapon implements Serializable {
@Id
@ManyToOne
@PrimaryKeyJoinColumn(name = "creature_id", referencedColumnName = "id")
private CreatureType creatureType;
@Id
@ManyToOne
@PrimaryKeyJoinColumn(name = "weapon_id", referencedColumnName = "id")
private Weapon weapon;
}
然后您可以按如下方式定义查询:
通过生物找到
"SELECT CreatureTypeWeapon WHERE creatureType = ?"
武器查找
"SELECT CreatureTypeWeapon WHERE weapon = ?"
通过生物和武器找到
"SELECT CreatureTypeWeapon WHERE creatureType = ? AND weapon = ?"
删除
em.delete(creatureTypeWeapon);