2012-10-31 78 views
0

我拥有类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; 
} 

这样做之后,就可以正常删除它,(这是可行的,甚至之前,但我很困惑,认为错误在那里)。

回答

0

您需要定义一个新的表,它是联接表CreatureTypeWeapon的。例如:通过生物

"SELECT CreatureTypeWeapon WHERE creatureType = ?" 

查找武器

"SELECT CreatureTypeWeapon WHERE 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 = ? AND weapon = ?" 

删除

em.delete(creatureTypeWeapon); 
+0

请参阅更新 – stewenson

0

难道你不能只删除CreatureTypeWeapon实体吗?我想,你不需要做找到,只是删除CreatureTypeWeapon实体它将删除与CreatureTypeWeapon的关联。

public class CreatureTypeWeaponDAOImpl implements CreatureTypeWeaponDAO { 
    void remove(CreatureTypeWeapon arg) { 
     /*Some init codes here*/ 
     session.delete(arg); 
    } 
} 
相关问题