Migrating from Hibernate 3.6 to 4.2: Hibernate自动生成外键

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

Migrating from Hibernate 3.6 to 4.2: Hibernate auto generates foreign keys

问题

以下是翻译好的内容:

问题

升级后,Hibernate开始自动生成一个指向相同表的外键。现在,在尝试持久化新客户时,会抛出ConstraintViolationException

细节

这里有我所说的一个图片:

Migrating from Hibernate 3.6 to 4.2: Hibernate自动生成外键

这是相应类的代码:

  1. @Entity
  2. @Table(name = "customers")
  3. @Inheritance(strategy = InheritanceType.JOINED)
  4. public abstract class Customer extends AbstractModel {
  5. public Customer(final Provider provider) {
  6. this.provider = provider;
  7. }
  8. @Required
  9. @ManyToOne(cascade = CascadeType.REFRESH)
  10. public Provider provider;
  11. @MaxSize(1023)
  12. public String note;
  13. public String getNote() { return note; }
  14. ...
  15. }

如您所见,它继承自AbstractModel,这是一个@MappedSuperclass,包含用于我们所有模型类的主键的id属性。它是一个@GeneratedValue

它本身是一个超类。我不知道它是否重要,所以我只会包括一个其子类的代码和架构:

Migrating from Hibernate 3.6 to 4.2: Hibernate自动生成外键

以及相应的代码:

  1. @Entity
  2. @Table(name="unregistered_customers")
  3. public class UnregisteredCustomer extends Customer {
  4. @MaxSize(MAX_SIZE_OF_NAMES_AND_IDENTIFIERS)
  5. @Column(nullable = false, length = MAX_SIZE_OF_NAMES_AND_IDENTIFIERS)
  6. public String userName;
  7. @Email
  8. @MaxSize(MAX_SIZE_OF_EMAIL_ADDRESSES)
  9. @Column(unique = false, length = MAX_SIZE_OF_EMAIL_ADDRESSES)
  10. public String email;
  11. @MaxSize(MAX_SIZE_OF_NAMES_AND_IDENTIFIERS)
  12. @Column(length = MAX_SIZE_OF_NAMES_AND_IDENTIFIERS)
  13. public String mobile;
  14. public UnregisteredCustomer(final Provider provider) {
  15. super(provider);
  16. }
  17. }

研究

我已经查阅了迁移指南,但其中没有与我的问题相关的内容。我还查看了Hibernate文档,特别是与@Inheritance相关的部分。不幸的是,我没有找到任何关于自动生成外键的信息。

问题

如何阻止Hibernate添加这个自引用外键?

编辑 1

根据您的请求,这是超类的代码:

  1. @MappedSuperclass
  2. public abstract class AbstractModel extends AbstractBaseModel {
  3. @Id
  4. @GeneratedValue
  5. public Long id;
  6. public Long getId() {
  7. return id;
  8. }
  9. @Override
  10. public Object _key() {
  11. return id;
  12. }
  13. }

还有超类的超类的代码:

  1. @MappedSuperclass
  2. public abstract class AbstractBaseModel extends GenericModel {
  3. public static final int MAX_SIZE_OF_NAMES_AND_IDENTIFIERS = 80;
  4. public static final int MAX_SIZE_OF_COMMENTS_AND_DESCRIPTIONS = 5000;
  5. public static final int MAX_LIST_SIZE = 30;
  6. public static final int MAX_SIZE_OF_EMAIL_ADDRESSES = 255;
  7. public static final int MAX_SIZE_OF_JSON_CONTENT_FIELDS = 65535;
  8. @Column(nullable = false, unique = true)
  9. public String uuid;
  10. @Column(nullable = false)
  11. public Long created;
  12. public DateTime getCreatedAsDate() {
  13. return DateUtil.dateTimeWithSystemTimezone(created);
  14. }
  15. @Column(nullable = false)
  16. public Long lastModified;
  17. @PrePersist
  18. protected void prePersist() {
  19. final Long nowInMillis = DateUtil.dateTimeWithSystemTimezone().getMillis();
  20. if (uuid == null) {
  21. uuid = UuidUtil.newUUIDAsString();
  22. Logger.trace("为实体创建了新的Uuid:%s", uuid);
  23. }
  24. if (created == null) {
  25. created = nowInMillis;
  26. }
  27. if (lastModified == null) {
  28. lastModified = nowInMillis;
  29. }
  30. }
  31. @PreUpdate
  32. protected void preUpdate() {
  33. lastModified = DateUtil.dateTimeWithSystemTimezone().getMillis();
  34. }
  35. @Override
  36. public boolean equals(final Object obj) {
  37. if (this == obj) {
  38. return true;
  39. }
  40. if (obj == null) {
  41. return false;
  42. }
  43. final AbstractBaseModel other = (AbstractBaseModel) obj;
  44. return new EqualsBuilder().append(uuid, other.uuid).isEquals();
  45. }
  46. @Override
  47. public int hashCode() {
  48. return new HashCodeBuilder().append(uuid).toHashCode();
  49. }
  50. }

希望这些信息对您有所帮助。如果您需要进一步的帮助,请随时告诉我。

英文:

As the title suggests: I am currently migrating from Hibernate 3.6 to 4.2.

PROBLEM

After the upgrade, Hibernate started to automatically generate a foreign key that points to the same table. Now, when trying to persist a new customer, a ConstraintViolationException is thrown.

DETAILS

Here's a picture of what I mean:

Migrating from Hibernate 3.6 to 4.2: Hibernate自动生成外键

Here is the code of the corresponding class:

  1. @Entity
  2. @Table(name = "customers")
  3. @Inheritance(strategy = InheritanceType.JOINED)
  4. public abstract class Customer extends AbstractModel {
  5. public Customer(final Provider provider) {
  6. this.provider = provider;
  7. }
  8. @Required
  9. @ManyToOne(cascade = CascadeType.REFRESH)
  10. public Provider provider;
  11. @MaxSize(1023)
  12. public String note;
  13. public String getNote() { return note; }
  14. ...
  15. }

As you can see, it extends from AbstractModel which is a @MappedSuperclass and contains the id property which serves as a primary key for all of our model classes. It's a @GeneratedValue.

It's a superclass itself. I don't know whether it's important so I am just going to include the code and schema of one of its child classes:

Migrating from Hibernate 3.6 to 4.2: Hibernate自动生成外键

And the corresponding code:

  1. @Entity
  2. @Table(name="unregistered_customers")
  3. public class UnregisteredCustomer extends Customer {
  4. @MaxSize(MAX_SIZE_OF_NAMES_AND_IDENTIFIERS)
  5. @Column(nullable = false, length = MAX_SIZE_OF_NAMES_AND_IDENTIFIERS)
  6. public String userName;
  7. @Email
  8. @MaxSize(MAX_SIZE_OF_EMAIL_ADDRESSES)
  9. @Column(unique = false, length = MAX_SIZE_OF_EMAIL_ADDRESSES)
  10. public String email;
  11. @MaxSize(MAX_SIZE_OF_NAMES_AND_IDENTIFIERS)
  12. @Column(length = MAX_SIZE_OF_NAMES_AND_IDENTIFIERS)
  13. public String mobile;
  14. public UnregisteredCustomer(final Provider provider) {
  15. super(provider);
  16. }

RESEARCH

I already looked into the migration guide but nothing in there seems to be related to my issue.
I also looked into the Hibernate documentation especially into the section dealing with @Inheritance. Sadly, I didn't find anything concerning auto generated foreign keys.

QUESTION

How do I stop Hibernate from adding this self-referencing foreign key?

EDIT 1
As requested, the super class:

  1. @MappedSuperclass
  2. public abstract class AbstractModel extends AbstractBaseModel {
  3. @Id
  4. @GeneratedValue
  5. public Long id;
  6. public Long getId() {
  7. return id;
  8. }
  9. @Override
  10. public Object _key() {
  11. return id;
  12. }
  13. }

Also, the super class of the super class:

  1. @MappedSuperclass
  2. public abstract class AbstractBaseModel extends GenericModel {
  3. public static final int MAX_SIZE_OF_NAMES_AND_IDENTIFIERS = 80;
  4. public static final int MAX_SIZE_OF_COMMENTS_AND_DESCRIPTIONS = 5000;
  5. public static final int MAX_LIST_SIZE = 30;
  6. public static final int MAX_SIZE_OF_EMAIL_ADDRESSES = 255;
  7. public static final int MAX_SIZE_OF_JSON_CONTENT_FIELDS = 65535;
  8. @Column(nullable = false, unique = true)
  9. public String uuid;
  10. @Column(nullable = false)
  11. public Long created;
  12. public DateTime getCreatedAsDate() {
  13. return DateUtil.dateTimeWithSystemTimezone(created);
  14. }
  15. @Column(nullable = false)
  16. public Long lastModified;
  17. @PrePersist
  18. protected void prePersist() {
  19. final Long nowInMillis = DateUtil.dateTimeWithSystemTimezone().getMillis();
  20. if (uuid == null) {
  21. uuid = UuidUtil.newUUIDAsString();
  22. Logger.trace("Created new Uuid for entity: %s", uuid);
  23. }
  24. if (created == null) {
  25. created = nowInMillis;
  26. }
  27. if (lastModified == null) {
  28. lastModified = nowInMillis;
  29. }
  30. }
  31. @PreUpdate
  32. protected void preUpdate() {
  33. lastModified = DateUtil.dateTimeWithSystemTimezone().getMillis();
  34. }
  35. @Override
  36. public boolean equals(final Object obj) {
  37. if (this == obj) {
  38. return true;
  39. }
  40. if (obj == null) {
  41. return false;
  42. }
  43. final AbstractBaseModel other = (AbstractBaseModel) obj;
  44. return new EqualsBuilder().append(uuid, other.uuid).isEquals();
  45. }
  46. @Override
  47. public int hashCode() {
  48. return new HashCodeBuilder().append(uuid).toHashCode();
  49. }
  50. }

答案1

得分: 2

Put @Inheritance(strategy = InheritanceType.JOINED) to the parent entity (AbstractModel) not to the child. And customize the foreign key constraint using @PrimaryKeyJoinColumn at your child entity. Check out Part 4 (Joined Table) at https://www.baeldung.com/hibernate-inheritance to see it more clearly!

英文:

Put @Inheritance(strategy = InheritanceType.JOINED) to the parent entity (AbstractModel) not to the child. And customize the foreign key constraint using @PrimaryKeyJoinColumn at your child entity. Check out Part 4 (Joined Table) at https://www.baeldung.com/hibernate-inheritance to see it more clearly!

huangapple
  • 本文由 发表于 2020年8月11日 16:45:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/63354638.html
匿名

发表评论

匿名网友

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

确定