英文:
AttributeOverride MappedSuperClass attribute with a different type
问题
我有一个作为MappedSuperclass使用的抽象类,如下所示:
@MappedSuperclass
@IdClass(LogId.class)
public abstract class Log {
private LocalDateTime moment;
private String pid;
// attributes omitted
private String type;
private String message;
@Id
public LocalDateTime getMoment() { return moment; }
@Id
public String getPid() { return pid; }
// getters/setters omitted
}
我的Log
类为每个实体提供相同的结构,具有标准属性type
和message
。每个实体表示数据库中的一张表,共享每个属性(@Id
和// omitted
部分)。列type
和message
可能具有不同的名称和类型。
我的第一个尝试是:
@Entity
@Table(name = "flow_catcher")
public class FlowCatcher extends Log {
@Override
@Column(name = "message_type")
public String getType() {
return super.getType();
}
@Override
@Column(name = "count")
@Convert(converter = StringToIntegerDbConverter.class)
public String getMessage() {
return super.getMessage();
}
}
根据这个帖子,我使用了@AttributeOverride
,像这样:
@Entity
@Table(name = "flow_catcher")
@AttributeOverride(name = "type", column = @Column(name = "message_type"))
@AttributeOverride(name = "message", column = @Column(name = "count"))
public class FlowCatcher extends Log {
}
但似乎不可能使用任何转换器将count
数据作为字符串而不是整数。以下是我的错误日志:
无法构建Hibernate SessionFactory;嵌套异常是
org.hibernate.tool.schema.spi.SchemaManagementException:
Schema-validation: 在表 [flow_catcher] 的列 [count] 中遇到错误的列类型;
发现 [int (Types#INTEGER)],但期望 [varchar(255) (Types#VARCHAR)]
有没有办法将我的count
列作为String
而不是Integer
获取?
附注:Hibernate的hbm2ddl.auto
设置为validate
,数据库模式无法更改。
编辑 1:我找到了一个有效的解决方案,但它使用了数据库中的另一列other_string_column
(未使用),这在我看来不太干净:
@Entity
@Table(name = "flow_catcher")
@AttributeOverride(name = "type", column = @Column(name = "message_type"))
@AttributeOverride(name = "message", column = @Column(name = "other_string_column"))
public class FlowCatcher extends Log{
private Integer count;
@Override
public String getMessage() {
return this.count.toString();
}
public Integer getCount() { return count; }
public void setCount(Integer count) { this.count = count; }
}
英文:
I have an Abstract class used as MappedSuperclass like :
@MappedSuperclass
@IdClass(LogId.class)
public abstract class Log {
private LocalDateTime moment;
private String pid;
// attributes omitted
private String type;
private String message;
@Id
public LocalDateTime getMoment() { return moment; }
@Id
public String getPid() { return pid; }
// getters/setters omitted
}
My Log
class provides to every entity the same structure with standard attributes type
and message
. Each entity represents a table in my database which share every attributes (@Id
and // omitted
ones). Columns type
and message
might have different names & types.
My first attempt was :
@Entity
@Table(name = "flow_catcher")
public class FlowCatcher extends Log {
@Override
@Column(name = "message_type")
public String getType() {
return super.getType();
}
@Override
@Column(name = "count")
@Convert(converter = StringToIntegerDbConverter.class)
public String getMessage() {
return super.getMessage();
}
}
Following this post I used @AttributeOverride
like :
@Entity
@Table(name = "flow_catcher")
@AttributeOverride(name = "type", column = @Column(name = "message_type"))
@AttributeOverride(name = "message", column = @Column(name = "count"))
public class FlowCatcher extends Log {
}
But it seems impossible to use any converter to get data count
as a String and not an Integer.
Here is my error log:
Unable to build Hibernate SessionFactory; nested exception is
org.hibernate.tool.schema.spi.SchemaManagementException:
Schema-validation: wrong column type encountered in column [count] in table [flow_catcher];
found [int (Types#INTEGER)], but expecting [varchar(255) (Types#VARCHAR)]
Is there any way to get my column count
as a String
and not an Integer
?
PS: Hibernate hbm2ddl.auto
is set on validate
and database scheme can't change.
EDIT 1: I found a working solution but it uses another (unused) column in my database other_string_column
which doesn't sound clean to me :
@Entity
@Table(name = "flow_catcher")
@AttributeOverride(name = "type", column = @Column(name = "message_type"))
@AttributeOverride(name = "message", column = @Column(name = "other_string_column"))
public class FlowCatcher extends Log{
private Integer count;
@Override
public String getMessage() {
return this.count.toString();
}
public Integer getCount() { return count; }
public void setCount(Integer count) { this.count = count; }
}
答案1
得分: 3
可以使用通用方式:
@MappedSuperclass
@IdClass(LogId.class)
public class Log<T extends Comparable> implements Serializable {
@Id
private LocalDateTime moment;
@Id
private String pid;
//此处添加所需的附加字段
// 不要指定映射
private T message;
}
@Entity
@Table(name = "flow_catcher")
@AttributeOverride(name = "type", column = @Column(name = "message_type"))
@AttributeOverride(name = "message", column = @Column(name = "count", columnDefinition = "BIGINT(15)"))
public class FlowCatcher extends Log<Integer> {
private static final long serialVersionUID = -3629698185247120860L;
}
@Entity
@Table(name = "flow_catcher_another_sample")
@AttributeOverride(name = "type", column = @Column(name = "message_type"))
@AttributeOverride(name = "message", column = @Column(name = "message", columnDefinition = "VARCHAR(20)"))
public class FlowCatcherString extends Log<String> {
private static final long serialVersionUID = -3629698185247120860L;
}
英文:
You can go with generic
@MappedSuperclass
@IdClass(LogId.class)
public class Log<T extends Comparable> implements Serializable {
@Id
private LocalDateTime moment;
@Id
private String pid;
//additional required fields here
// Do NOT SPECIFY MAPPING
private T message;
}
@Entity
@Table(name = "flow_catcher")
@AttributeOverride(name = "type", column = @Column(name = "message_type"))
@AttributeOverride(name = "message", column = @Column(name = "count", columnDefinition = "BIGINT(15)"))
public class FlowCatcher extends Log<Integer> {
private static final long serialVersionUID = -3629698185247120860L;
}
@Entity
@Table(name = "flow_catcher_another_sample")
@AttributeOverride(name = "type", column = @Column(name = "message_type"))
@AttributeOverride(name = "message", column = @Column(name = "message", columnDefinition = "VARCHAR(20)"))
public class FlowCatcherString extends Log<String> {
private static final long serialVersionUID = -3629698185247120860L;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论