我正在尝试在以下数据库表的Hibernate中创建映射类:
CREATE TABLE values (
id SMALLINT,
name NVARCHAR(50) NOT NULL,
type NVARCHAR(10) NOT NULL,
text NVARCHAR(MAX) NULL,
numeric NUMERIC NULL,
boolean BIT NULL,
date DATETIME NULL,
CONSTRAINT c1 CHECK(type IN ('TEXT','NUMERIC','BOOLEAN','DATE'))
);
目前我有以下实现,但我不想重新定义每个子类中的每个属性,因为它不使用父代的通用实现:
值
@Entity
@Table(name = "values")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type")
public abstract class Value<T extends Serializable> {
@Id
private int id;
private String name;
@Transient
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
值类型
@Entity
@DiscriminatorValue("TEXT")
public class TextValue extends Value<String> {
private String text;
@Override
public String getValue() {
return text;
}
}
@Entity
@DiscriminatorValue("NUMERIC")
public class NumericValue extends Value<Double> {
private Double numeric;
@Override
public Double getValue() {
return numeric;
}
}
@Entity
@DiscriminatorValue("BOOLEAN")
public class BooleanValue extends Value<Boolean> {
private Boolean boolean;
@Override
public Boolean getValue() {
return boolean;
}
}
@Entity
@DiscriminatorValue("DATE")
public class DateValue extends Value<LocalDateTime> {
private LocalDateTime date;
@Override
public LocalDateTime getValue() {
return date;
}
}
我尝试使用@AttributeOverride
来更改每个子类中的列名,但它没有效果。
如果有另一种方法可以实现上表中的键值结构,并且可以使用Java中的泛型进行映射也很有价值。
答案 0 :(得分:0)
尝试使用不同的映射,而不是@Transient值:
@Entity
@Table(name = "values")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type")
public abstract class Value<T extends Serializable>
{
@Id
protected int id;
protected String name;
public abstract T getValue();
public abstract void setValue(T value);
}
@Entity
@DiscriminatorValue("TEXT")
public class TextValue extends Value<String>
{
@Column(name = "text")
private String value;
@Override
public String getValue()
{
return value;
}
@Override
public void setValue(String value)
{
this.value = value;
}
}
@Entity
@DiscriminatorValue("NUMERIC")
public class NumericValue extends Value<Double>
{
@Column(name = "numeric")
private Double value;
@Override
public Double getValue()
{
return value;
}
@Override
public void setValue(Double value)
{
this.value = value;
}
}
等等
嗯,好处非常有限,因为我觉得你可能想要这样的东西:
@Entity
public class Something
{
...
@OneToMany(cascade = ALL, orphanRemoval = true)
@JoinColumn(name = "SOMETHING_ID")
private Set<Value<?>> values = new LinkedHashSet<>();
...
}
在这种情况下,唯一的好处是内部值由ORM转换为正确的类,因此这不是您的责任。
尽管如此,您必须(并且无法避免,与任何其他模型一起使用)使用繁琐的instanceof
污染您的业务逻辑/表示控制器。