Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java hibernate—持久化策略模式的组合界面_Java_Hibernate_Design Patterns_Database Design_Relational Database - Fatal编程技术网

Java hibernate—持久化策略模式的组合界面

Java hibernate—持久化策略模式的组合界面,java,hibernate,design-patterns,database-design,relational-database,Java,Hibernate,Design Patterns,Database Design,Relational Database,我的班级结构如下: public abstract class Creature{ private String name; //strategy pattern composition private SkillInterface skill; } public interface SkillInterface { void attack(); } public class NoSkill implements SkillInterface { @Overri

我的班级结构如下:

public abstract class Creature{
   private String name;
   //strategy pattern composition
   private SkillInterface skill;
}

public interface SkillInterface {
   void attack();
}

public class NoSkill implements SkillInterface {
   @Override
   public void attack() {
       //statements
   }
}
我的目标是将对象持久化到数据库中的一个表中。SkillInterface的子类没有任何字段。当它们决定行为时,我想将选定的SkillInterface类名转换为字符串,因为我只需要使用类似skill.getClass().getSimpleName()的字符串来持久化生物当前技能策略的类名。我尝试用@Converter注释实现它,使用AttributeConverter类将SkillInterface转换为字符串并保存,但始终存在映射异常。我希望能够将其保存为字符串并检索为SkillInterface对象


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

您可以使用代理字段来解决此问题,如下所示:

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

看起来我已经找到了一个基本的解决方案,可以用来持久化策略模式接口的实现。在保存到数据库时,我使用@Converter注释和AttributeConverter类将策略类名称转换为列,并将检索到的字符串转换回策略类,如下所示:

@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
    }
}
@实体
公营动物{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
私有int-id;
@Convert(converter=SkillConverter.class)
私人技术交流技能;
}
公共类SkillConverter实现AttributeConverter{
@凌驾
公共字符串convertToDatabaseColumn(SkillInterface技能){
返回skill.getClass().getSimpleName().toLowerCase();
}
@凌驾
public SkillInterface convertToEntityAttribute(字符串dbData){
//作为工厂工作
if(dbData.equals(“noskill”)){
返回新的NoSkill();
}else if(dbData.equals(“axe”)){
归还新斧头();
}
返回null;
}
}
公共接口技术接口{
公共字符串getSkill();
无效攻击();
}
公共类NoSkill实现SkillInterface{
公共字符串getSkill(){
返回getClass().getSimpleName();
}
@凌驾
公开无效攻击(){
//战略声明
}
}

您还可以发布您的表结构以及数据的外观吗?通过引用检索接口是什么意思?你们打算取回整个物体吗?嗨,阿米斯,我编辑了我的问题并给出了更多细节。我想做的是能够在数据库中的一个表中保存生物对象。我想将SkillInterface转换为String,因为我只需要保留生物当前技能策略的类名。如果需要,可以提供更多详细信息。如果您只需要保留当前技能策略的名称,为什么不使用Enum来实现类似的功能?我只是想看看是否可以使用接口及其子类来实现和保留策略模式。Enum可能是个好主意,但添加所有方法声明并失去接口的灵活性不是一个单一的Enum吗?好的。因此,如果我理解正确,您可能正在寻找结合鉴别器值的继承。看一看:我考虑过这种方法,但每次检索对象时,都需要一个额外的工厂模式来处理将skillName字符串转换为SkillInterface子类的过程。我认为在Hibernate中应该有一个更方便的解决方案,比如@Convert annotation。它实际上是一个使用它的完美场所,但由于映射异常或其他问题,我无法以某种方式构建它。