Hibernate使用数据类实体的子类

huangapple go评论54阅读模式
英文:

Hibernate use subclass of data class entity

问题

我有一个类似这样的实体:

    @NoArgsConstructor
    @AllArgsConstructor
    @Getter
    @Entity
    public class EBase {
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      @Column(name = "e_id", nullable = false)
      private Integer id;
  
      @Column(name = "name")
      protected String name;

      @Column(name = "letters")
      protected byte letters;
    }

要修改数据,我使用另一个类:

    @NoArgsConstructor
    @AllArgsConstructor
    public class E extends EBase {
      public void setName(String name) {
        super.name = name;
        super.letters = (byte) name.length();
      }
    }

我知道可以以非常不同的方式解决这个问题,我绝不会像这样存储字符串的长度。但这有助于可视化我的问题。我希望有一个只有Getter和Setter而没有“真正”其他方法的实体。
现在让我们创建一个实体:

    public class Main {
      public static void main(String[] args) {
        final E e = new E();
        e.setName("Test");
        Database.getSession().save(e);
      }
    }

我的问题是:这是否可行?

我尝试了一个工厂类:

@RequiredArgsConstructor
@Getter
class EFactory {
  private final EBase e;
  public void setName(String name) {
    e.setName(name);
    e.setLetters((byte) name.length());  // EBase中实现了setter
  }

  public EBase get() {
    return e;
  }
}

并使用以下代码:

public class Main {
  public static void main(String[] args) {
    EBase e = new EBase();
    e = new EFactory(e).setName("Test").get();
    Database.getSession().save(e);
  }
}

但这不是很优雅。上述提到的解决方案是否可能,即使E不是实体?

英文:

I have an entity like this:

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Entity
public class EBase {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "e_id", nullable = false)
  private Integer id;

  @Column(name = "name")
  protected String name;

  @Column(name = "letters")
  protected byte letters;
}

To modify data I use an other class:

@NoArgsConstructor
@AllArgsConstructor
public class E extends EBase {
  public void setName(String name) {
    super.name = name;
    super.letters = (byte) name.length();
  }
}

I know that can be solved very different and I would never store the length of a string like this. But its good to visualize my problem. I want to have an entity that has only Getters and Setters no "real" other methods.
Now lets create an entity:

public class Main {
  public static void main(String[] args) {
    final E e = new E();
    e.setName("Test");
    Database.getSession().save(e);
  }
}

My question is: Is this possible?

I tried a factory class like

@RequiredArgsConstructor
@Getter
class EFactory {
  private final EBase e;
  public void setName(String name) {
    e.setName(name);
    e.setLetters((byte) name.length());  // setters in EBase implemented
  }

  public EBase get() {
    return e;
  }
  
}

with:

public class Main {
  public static void main(String[] args) {
    EBase e = new EBase();
    e = new EFactory(e).setName("Test").get();
    Database.getSession().save(e);
  }
}

but this is not very fancy. Is the solution mentioned above possible even if E is not an entity?

答案1

得分: 1

生成器模式用于创建不可变对象。例如:

public class EBase {
    private final Integer id;
    private final String name;
    private final byte letters;

    private EBase(Builder builder) {
        this.id = builder.id;
        this.name = builder.name;
        this.letters = builder.letters;
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public byte getLetters() {
        return letters;
    }

    protected static class Builder {
        private Integer id;
        private String name;
        private byte letters;

        public Builder setId(Integer id) {
            this.id = id;
            return this;
        }

        public Builder setName(String name) {
            this.name = name;
            return this;
        }

        public Builder setLetters(byte letters) {
            this.letters = letters;
            return this;
        }

        public EBase build() {
            return new EBase(this);
        }
    }
}

现在,如果您正在使用Hibernate,您希望将对象存储在SQL数据库中,如果可以存储对象而无需修改它们,大多数情况下,您将希望具有修改它们的能力。

当然,您可以将所有的setter移动到另一个类中,就像这样:

public class EBase {
    private Integer id;
    private String name;
    private byte letters;

    public interface Updater {
        public Updater setId(Integer id);
        public Updater setName(String name);
        public Updater setLetters(byte letters);
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public byte getLetters() {
        return letters;
    }

    public Updater getUpdater() {
        return new Updater() {
            @Override
            public Updater setId(Integer newId) {
                id = newId;
                return this;
            }

            @Override
            public Updater setName(String newName) {
                name = newName;
                return this;
            }

            @Override
            public Updater setLetters(byte newLetters) {
                letters = newLetters;
                return this;
            }
        };
    }
}

但我不明白为什么您需要继承。

话虽如此,我建议您都不使用这些模式,只需在同一个类中声明getter和setter方法。

英文:

The builder pattern is used to create immutable objects. For instance:

public class EBase {
    private final Integer id;
    private final String name;
    private final byte letters;

    private EBase(Builder builder) {
        this.id = builder.id;
        this.name = builder.name;
        this.letters = builder.letters;
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public byte getLetters() {
        return letters;
    }

    protected static class Builder {
        private Integer id;
        private String name;
        private byte letters;

        public Builder setId(Integer id) {
            this.id = id;
            return this;
        }

        public Builder setName(String name) {
            this.name = name;
            return this;
        }

        public Builder setLetters(byte letters) {
            this.letters = letters;
            return this;
        }

        public EBase build() {
            return new EBase(this);
        }
    }
}

Now, if you're using hibernate, you want to store objects in an SQL database, and, if you can store objects without ever modifying them, most of the time, you will want to have the ability to modify them.

Of course you could move all your setters to another class, like this:

public class EBase {
    private Integer id;
    private String name;
    private byte letters;

    public interface Updater {
        public Updater setId(Integer id);
        public Updater setName(String name);
        public Updater setLetters(byte letters);
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public byte getLetters() {
        return letters;
    }

    public Updater getUpdater() {
        return new Updater() {
            @Override
            public Updater setId(Integer newId) {
                id = newId;
                return this;
            }

            @Override
            public Updater setName(String newName) {
                name = newName;
                return this;
            }

            @Override
            public Updater setLetters(byte newLetters) {
                letters = newLetters;
                return this;
            }
        };
    }
}

But I don't see why you would need inheritance.

That said, I would recommand you to use neither of those patterns, and just declare getters and setters in the same class.

huangapple
  • 本文由 发表于 2023年2月27日 17:13:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75578561.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定