Java 8 и MySQL здесь, возникают некоторые проблемы с получением проверки схемы JPA / Hibernate, работающей с моей моделью наследования объектов. У меня Hibernate установлен в «режим проверки» (то есть он должен проверять только мои Java классы и их аннотации JPA / Hibernate по существующей структуре БД).
Мои Java классы:
// All my Java entities extend BaseEntity which just contains a few fields that
// all my DB tables will also have.
@MappedSuperclass
@Data
@EqualsAndHashCode(callSuper=false)
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String refId;
}
// Base class for several Org subclasses. I would like these subclasses to all share
// the same "organizations" table under the hood
@Entity
@Table(name = "organizations")
@AttributeOverrides({
@AttributeOverride(name = "id", column = @Column(name = "organization_id")),
@AttributeOverride(name = "refId", column = @Column(name = "organization_ref_id"))
})
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="organization_type", discriminatorType = DiscriminatorType.STRING)
@Data
@EqualsAndHashCode(callSuper=false)
public class Organization extends BaseEntity {
@Enumerated(EnumType.STRING)
@Column(name = "organization_type")
private OrgType type;
@Column(name = "organization_name")
private String name;
@Column(name = "organization_slug")
private String slug;
@OneToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "organization_address_id", referencedColumnName = "address_id")
private Address address;
@Column(name = "organization_website")
private String website;
@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(
name="organizational_contacts",
joinColumns={
@JoinColumn(name="organization_id")
},
inverseJoinColumns= {
@JoinColumn(name = "contact_id")
}
)
private Set<Contact> keyContacts;
@Column(name = "organization_phone")
private String phone;
@Column(name = "organization_domain_name")
private String domainName;
@Column(name = "organization_preferred_locale")
private String preferredLocale;
}
@Entity(name = "Vendor")
@DiscriminatorValue("VENDOR")
@Data
@EqualsAndHashCode(callSuper=false)
public class Vendor extends Organization {
@Column(name = "organization_vendor_naics_code")
private String naicsCode;
}
А вот моя схема БД:
CREATE TABLE IF NOT EXISTS organizations (
organization_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
organization_ref_id VARCHAR(36) NOT NULL,
organization_type VARCHAR(50) NOT NULL,
organization_name VARCHAR(100) NOT NULL,
organization_slug VARCHAR(100) NOT NULL,
organization_address_id BIGINT UNSIGNED NOT NULL,
organization_website VARCHAR(250) NOT NULL,
organization_phone VARCHAR(25) NOT NULL,
organization_domain_name VARCHAR(250) NOT NULL,
organization_preferred_locale VARCHAR(25) NOT NULL,
-- subclass fields; must ALL be nullable
organization_vendor_naics_code VARCHAR(6),
organization_purchaser_country VARCHAR(3),
CONSTRAINT pk_organizations PRIMARY KEY (organization_id),
CONSTRAINT fk_organizations_address_id FOREIGN KEY (organization_address_id) REFERENCES addresses (address_id),
INDEX idx_organizations_organization_ref_id (organization_ref_id),
INDEX idx_organizations_organization_slug (organization_slug),
INDEX idx_organizations_organization_domain_name (organization_domain_name),
CONSTRAINT uc_organizations_organization_ref_id UNIQUE (organization_ref_id),
CONSTRAINT uc_organizations_organization_slug UNIQUE (organization_slug),
CONSTRAINT uc_organizations_organization_domain_name UNIQUE (organization_domain_name)
);
Когда я запускаю свое приложение, я получаю:
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: com.example.myapp.domain.entities.orgs.Vendor column: organization_type (should be mapped with insert="false" update="false")
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:862)
at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:880)
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:902)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:634)
at org.hibernate.mapping.SingleTableSubclass.validate(SingleTableSubclass.java:54)
at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:351)
По словам богов Google, это исключение возникает когда два класса пытаются сопоставить один и тот же столбец, но это то, что я хочу, верно ?! Я хочу, чтобы было два подкласса Organization
, каждый из которых имеет одну и ту же таблицу organizations
(следовательно, стратегию SINGLE_TABLE
), и я хочу, чтобы перечисление / строка Organization#type : OrgType
было дискриминатором, сообщающим JPA / Hibernate, какой подкласс мы иметь дело с!
Кто-нибудь может заметить, где я ошибаюсь?