java - 从 Hibernate 3.6 迁移到 4.2:Hibernate 自动生成外键
问题描述
正如标题所示:我目前正在从 Hibernate 3.6 迁移到 4.2。
问题
升级后,Hibernate 开始自动生成指向同一张表的外键。现在,当尝试保持新客户时,ConstraintViolationException
会抛出 a。
细节
这是我的意思的图片:
下面是对应类的代码:
@Entity
@Table(name = "customers")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Customer extends AbstractModel {
public Customer(final Provider provider) {
this.provider = provider;
}
@Required
@ManyToOne(cascade = CascadeType.REFRESH)
public Provider provider;
@MaxSize(1023)
public String note;
public String getNote() { return note; }
...
}
如您所见,它扩展自AbstractModel
which is a@MappedSuperclass
并包含id
用作我们所有模型类的主键的属性。这是一个@GeneratedValue
。
它本身就是一个超类。我不知道它是否重要,所以我只想包含其子类之一的代码和架构:
以及对应的代码:
@Entity
@Table(name="unregistered_customers")
public class UnregisteredCustomer extends Customer {
@MaxSize(MAX_SIZE_OF_NAMES_AND_IDENTIFIERS)
@Column(nullable = false, length = MAX_SIZE_OF_NAMES_AND_IDENTIFIERS)
public String userName;
@Email
@MaxSize(MAX_SIZE_OF_EMAIL_ADDRESSES)
@Column(unique = false, length = MAX_SIZE_OF_EMAIL_ADDRESSES)
public String email;
@MaxSize(MAX_SIZE_OF_NAMES_AND_IDENTIFIERS)
@Column(length = MAX_SIZE_OF_NAMES_AND_IDENTIFIERS)
public String mobile;
public UnregisteredCustomer(final Provider provider) {
super(provider);
}
研究
我已经查看了迁移指南,但其中似乎没有任何内容与我的问题有关。我还查看了 Hibernate 文档,尤其是处理@Inheritance
. 可悲的是,我没有发现任何有关自动生成的外键的信息。
问题
如何阻止 Hibernate 添加这个自引用外键?
编辑 1 根据要求,超类:
@MappedSuperclass
public abstract class AbstractModel extends AbstractBaseModel {
@Id
@GeneratedValue
public Long id;
public Long getId() {
return id;
}
@Override
public Object _key() {
return id;
}
}
还有,超类的超类:
@MappedSuperclass
public abstract class AbstractBaseModel extends GenericModel {
public static final int MAX_SIZE_OF_NAMES_AND_IDENTIFIERS = 80;
public static final int MAX_SIZE_OF_COMMENTS_AND_DESCRIPTIONS = 5000;
public static final int MAX_LIST_SIZE = 30;
public static final int MAX_SIZE_OF_EMAIL_ADDRESSES = 255;
public static final int MAX_SIZE_OF_JSON_CONTENT_FIELDS = 65535;
@Column(nullable = false, unique = true)
public String uuid;
@Column(nullable = false)
public Long created;
public DateTime getCreatedAsDate() {
return DateUtil.dateTimeWithSystemTimezone(created);
}
@Column(nullable = false)
public Long lastModified;
@PrePersist
protected void prePersist() {
final Long nowInMillis = DateUtil.dateTimeWithSystemTimezone().getMillis();
if (uuid == null) {
uuid = UuidUtil.newUUIDAsString();
Logger.trace("Created new Uuid for entity: %s", uuid);
}
if (created == null) {
created = nowInMillis;
}
if (lastModified == null) {
lastModified = nowInMillis;
}
}
@PreUpdate
protected void preUpdate() {
lastModified = DateUtil.dateTimeWithSystemTimezone().getMillis();
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
final AbstractBaseModel other = (AbstractBaseModel) obj;
return new EqualsBuilder().append(uuid, other.uuid).isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(uuid).toHashCode();
}
}
解决方案
将 @Inheritance(strategy = InheritanceType.JOINED) 放到父实体(AbstractModel)而不是子实体。并在您的子实体中使用 @PrimaryKeyJoinColumn 自定义外键约束。请查看https://www.baeldung.com/hibernate-inheritance上的第 4 部分(连接表)以更清楚地看到它!
推荐阅读
- directx - 如何使用 C 语言在 DirectX 11 中呈现文本
- java - 当一个函数使用另一个函数的返回数据时如何使用模拟?
- r - 如何使用 tidyeval 从传递给 UDF 的一个参数的值列表中获取特定值
- javascript - 未找到 NodeJS discord-rpc 应用程序
- android - 从模块管理请求应用权限
- python - 如何使用正则表达式匹配 10 个带或不带空格的数字?
- python - 为什么我的 Python “if-else” 块不会产生与具有相同逻辑的两个 if 语句相同的结果?
- postgresql - 当我从授权服务器获得 UUID 时,是否需要使用自动生成的列作为主键?
- python - 有没有办法使用 sudo 访问文件在 python 中监视文件系统?
- c++ - 有没有办法导航到 VSCode 或 CLion for CPP 中另一个文件中的函数定义?