简体   繁体   English

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

[英]DAO class for association entity with an attribute - how to implement it?

I have class CreatureType and Weapon (the best weapon to use against some creature) and I need to model the fact that a weapon has various efficiency against particular CreatureType. 我有CreatureType和Weapon类(对某些生物使用的最佳武器),我需要对以下事实进行建模:武器对特定的CreatureType具有各种效率。 So I created the association entity CreatureTypeWeapon which has the efficiency attribute. 因此,我创建了具有效率属性的关联实体CreatureTypeWeapon。

I coded it in this way (the principle is the same) http://uaihebert.com/?p=1674&page=22 我以这种方式编码(原理是相同的) http://uaihebert.com/?p=1674&page=22

The reason why I am asking this question is that I don't know how to implement dao class for the association entity. 我之所以问这个问题,是因为我不知道如何为关联实体实现dao类。

I have the DAO class for CreatureType and I have the DAO class for Weapon which implements the interfaces with CRUD operations. 我具有用于CreatureType的DAO类,并且具有用于Weapon的DAO类,该类实现具有CRUD操作的接口。

But I am somehow missing a way ho to deal with CRUD operations on the association entity. 但我莫名其妙地失踪浩一的方式来处理在关联实体的CRUD操作。 Let's say I have this DAO 假设我有这个DAO

public class CreatureTypeWeaponDAOImpl implements CreatureTypeWeaponDAO {

    @Override
    public void create(CreatureTypeWeapon creatureTypeWeapon) {
        // implementation
    }
    // ... other CRUD methods
}

I use it like this: 我这样使用它:

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

But the question is, how to implement it? 但是问题是,如何实施? I am able to persist it normally, but let's say I am going to remove this relationship: 我能坚持正常,但让我们说,我要去掉这种关系:

dao.remove(creatureTypeWeapon);

Which could be implemented like this 可以这样实现

public class CreatureTypeWeaponDAOImpl implements CreatureTypeWeaponDAO {
    void remove(CreatureTypeWeapon arg) {
        CreatureTypeWeapon toRemove = em.find(/* WHAT TO PUT HERE */);
        em.remove(toRemove);
    }
}

Normally, I put there 通常我放在那里

em.find(CreatureTypeWeapon.class, arg.getId());

but there is not "id" in the association entity .... 但关联实体中没有“ id” ..

UPDATE 更新

Ok so this is the way how I am getting a CreatureTypeWeapon instances in the CreatureTypeWeaponDAOImpl 好的,这就是我在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();

Getting seems to be ok but when I am going to remove it in the remove method as simple as em.remove(creatureTypeWeapon); 似乎可以,但是当我要在删除方法中将其删除时,就像em.remove(creatureTypeWeapon)一样简单; (as advised) I am getting this error: (如建议)我收到此错误:

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)

This is a way how I am testing it: 这是我测试的一种方式:

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

UPDATE #2 更新#2

Ok I got it, the reason there was such error was that when query.getSingleResult() throws NoResultException, it means that when I try to get the entity after its removing in the test, there is no such record, so that method throws an execption, which is good. 好的,我明白了,原因是发生了这样的错误,当query.getSingleResult()抛出NoResultException时,这意味着当我在测试中删除实体后尝试获取该实体时,没有这样的记录,因此该方法抛出了执行,这很好。 I handled it like this: 我这样处理:

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

After doing so, it is possible to remove it normally, (it was doable even before it but I was confused and thought the error was there). 这样做之后,可以正常将其删除(即使在此之前它也是可行的,但我感到困惑并认为错误在那里)。

Couldn't you just delete the CreatureTypeWeapon entity? 您不能只删除CreatureTypeWeapon实体吗? I think you don't need to do a find , just deleting the CreatureTypeWeapon entity it would remove the association with the CreatureType and Weapon . 我认为您无需进行查找 ,只需删除CreatureTypeWeapon实体即可删除与CreatureTypeWeapon的关联。

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

you need to define a new table that is the join of the table CreatureType and Weapon . 您需要定义一个新表,该表是表CreatureTypeWeapon For instance: 例如:

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

you can then define your queries as follows: 然后,您可以按以下方式定义查询:

Find by creature 按生物查找

"SELECT CreatureTypeWeapon WHERE creatureType = ?"

Find by weapon 通过武器查找

"SELECT CreatureTypeWeapon WHERE weapon = ?"

Find by creature and weapon 按生物和武器查找

"SELECT  CreatureTypeWeapon WHERE creatureType = ? AND weapon = ?"

Delete 删除

em.delete(creatureTypeWeapon);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM