有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

具有属性的关联实体的java DAO类如何实现?

我有类CreatureType和武器(对付某些生物最好的武器),我需要模拟一种武器对抗特定CreatureType的效率。因此,我创建了具有效率属性的关联实体CreatureTypeWearm

我是这样编码的(原理是一样的)http://uaihebert.com/?p=1674&page=22

我问这个问题的原因是我不知道如何为关联实体实现dao类

我有CreatureType的DAO类和武器的DAO类,它们实现了CRUD操作的接口

但不知何故,我错过了处理协会实体上CRUD操作的方法。假设我有这把刀

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中获取CreatureType武器实例的方法

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();

获取似乎是可以的,但是当我要用像em.remove(CreatureTypeAnswarm)这样简单的移除方法移除它时;(根据建议)我收到以下错误:

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

好的,我知道了,出现这种错误的原因是当查询时。getSingleResult()抛出NoResultException,这意味着当我在测试中删除实体后尝试获取该实体时,没有这样的记录,因此该方法抛出一个execption,这很好。我是这样处理的:

try {
    return query.getSingleResult();
} catch(NoResultException ex) {
    return null;
}

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


共 (2) 个答案

  1. # 1 楼答案

    你不能直接删除CreatureTypeWeapon实体吗?我认为您不需要执行查找,只需删除CreatureTypeWeapon实体即可删除与CreatureTypeWeapon的关联

    public class CreatureTypeWeaponDAOImpl implements CreatureTypeWeaponDAO {
        void remove(CreatureTypeWeapon arg) {
            /*Some init codes here*/
            session.delete(arg);
        }
    }
    
  2. # 2 楼答案

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

    @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);