休眠-保持策略模式的组合界面

时间:2018-07-02 14:21:52

标签: java hibernate design-patterns database-design relational-database

我具有以下类结构:

/usr/lib/x86_64-linux-gnu$ ls libhdf*
libhdf5_cpp.a                     libhdf5_serial_hl.a
libhdf5_cpp.so                    libhdf5_serialhl_fortran.a
libhdf5_cpp.so.11                 libhdf5_serialhl_fortran.so
libhdf5_cpp.so.11.0.0             libhdf5_serialhl_fortran.so.10
libhdf5_hl_cpp.a                  libhdf5_serialhl_fortran.so.10.0.2
libhdf5_hl_cpp.so                 libhdf5_serial_hl.so
libhdf5_hl_cpp.so.11              libhdf5_serial_hl.so.10
libhdf5_hl_cpp.so.11.0.0          libhdf5_serial_hl.so.10.0.2
libhdf5_hl.so                     libhdf5_serial.settings
libhdf5_serial.a                  libhdf5_serial.so
libhdf5_serial_fortran.a          libhdf5_serial.so.10
libhdf5_serial_fortran.so         libhdf5_serial.so.10.1.0
libhdf5_serial_fortran.so.10      libhdf5.so
libhdf5_serial_fortran.so.10.0.2

我的目标是将Creature对象保留在数据库的一张表中。 SkillInterface的子类没有任何字段。当他们确定行为时,我想将选定的SkillInterface类名称转换为String,因为我只需要使用Skill.getClass()。getSimpleName()这样的String来保留生物当前技能策略的类名称。我尝试使用@Converter注释来实现它,使用AttributeConverter类将SkillInterface转换为String并保存,但是始终有映射异常。我希望能够将其保存为String并作为SkillInterface对象进行检索。

但是我如何用Hibernate实现它呢?还是我有设计错误?

2 个答案:

答案 0 :(得分:3)

好吧,看来我已经找到了基本的解决方案,可以用来保留策略模式接口的实现。我使用@Converter批注和AttributeConverter类将策略类名称转换为列,同时保存到数据库中,并将检索到的String强制转换回策略类,如下所示:

@Entity
public class Creature {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Convert(converter = SkillConverter.class)
    private SkillInterface skill;
}

public class SkillConverter implements AttributeConverter<SkillInterface,String> {
    @Override
    public String convertToDatabaseColumn(SkillInterface skill) {
        return skill.getClass().getSimpleName().toLowerCase();
    }

    @Override
    public SkillInterface convertToEntityAttribute(String dbData) {
        //works as a factory
        if (dbData.equals("noskill")) {
            return new NoSkill();
        } else if (dbData.equals("axe")) {
            return new Axe();
        }
        return null;
    }
}

public interface SkillInterface {
    public String getSkill();

    void attack();
}


public class NoSkill implements SkillInterface{
    public String getSkill() {
        return getClass().getSimpleName();
    }

    @Override
    public void attack() {
        //strategy statements
    }
}

答案 1 :(得分:0)

您可以像下面这样使用代理字段:

abstract class Creature {
    @Column
    private String name;
    // strategy pattern composition
    private SkillInterface skill;

    @Column
    private String skillName;

    public String getSkillName() {
        return skill.getClass().getSimpleName();
    }

    public void setSkillName(String skillName) {
        //ignore
    }
}