使用组合键审核多对多联接

时间:2018-10-17 14:05:04

标签: java hibernate jpa hibernate-envers

我有一些具有如下关系的实体: Simplified ERD

联接表都具有其他字段(未显示)。

我在审核OrderOutletProducts的联接时遇到困难。

我的尝试

OutletProduct

@Audited
@Entity
public class OutletProduct {

    @EmbeddedId
    private OutletProductPk pk;

    @ManyToOne
    @MapsId("outletId")
    @JoinColumn(name = "outlet_id")
    private Outlet outlet;

    @ManyToOne
    @MapsId("productId")
    @JoinColumn(name = "product_id")
    private Product product;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "outletProduct")
    private Set<OrderOutletProduct> orderOutletProducts = new HashSet<OrderOutletProduct>();
}

OutletProductPk

@Embeddable
public class OutletProductPk implements Serializable { 

    @Column(name = "outletId")
    private Long outletId;

    @Column(name = "productId")
    private Long productId;

    // equals, hashcode, etc...
}

OrderOutletProduct

@Audited
@Entity
public class OrderOutletProduct {

    @EmbeddedId
    private OrderOutletProductPk pk;

    @ManyToOne
    @MapsId("orderId")
    @JoinColumn(name = "order_id")
    private Order order;

    @ManyToOne
    @MapsId("outletProductPk")
    @JoinColumns({
        @JoinColumn(name = "outlet_id"),
        @JoinColumn(name = "product_id"),
    })
    private OutletProduct outletProduct;
}

OrderOutletProductPk

@Embeddable
public class OrderOutletProductPk implements Serializable { 

    private Long orderId;

    private OutletProductPk outletProductPk;

    // equals, hashcode, etc...
}

结果是:

Invocation of init method failed; nested exception is org.hibernate.MappingException: Type not supported: org.hibernate.type.ComponentType
[...]
Caused by: org.hibernate.MappingException: Type not supported: org.hibernate.type.ComponentType
        at org.hibernate.envers.configuration.internal.metadata.IdMetadataGenerator.addIdProperties(IdMetadataGenerator.java:80)
        at org.hibernate.envers.configuration.internal.metadata.IdMetadataGenerator.addId(IdMetadataGenerator.java:144)
        at org.hibernate.envers.configuration.internal.metadata.AuditMetadataGenerator.generateFirstPass(AuditMetadataGenerator.java:632)
        at org.hibernate.envers.configuration.internal.EntitiesConfigurator.configure(EntitiesConfigurator.java:94)
        at org.hibernate.envers.boot.internal.EnversServiceImpl.doInitialize(EnversServiceImpl.java:152)
        at org.hibernate.envers.boot.internal.EnversServiceImpl.initialize(EnversServiceImpl.java:117)
        at org.hibernate.envers.boot.internal.AdditionalJaxbMappingProducerImpl.produceAdditionalMappings(AdditionalJaxbMappingProducerImpl.java:99)
        at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:288)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:848)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:875)
        at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:135)
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:340)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:319)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
        ... 59 more

堆栈跟踪中存在envers导致我尝试删除@Audited,但是这种尝试遇到了未经审计的实体与已审计的实体合并的投诉,并且在取消审计我的整个架构时消除了该错误,完全没有我的要求。

我正在将Hibernate 5.1.12.Final与相应的Envers一起使用。

编辑:问题似乎出在here上。

2 个答案:

答案 0 :(得分:0)

我认为您的问题出在列名上。在OutletProductPK中,您使用

@Column(name = "outletId")
private Long outletId;

@Column(name = "productId")
private Long productId;

,在其他类中,您使用product_id和outlet_id。数据库中各列的名称是什么?

答案 1 :(得分:0)

当我删除@JoinColumn批注,@Audit批注并将Order表重命名为Orders时,一切似乎都可以建立。因此,它的根源似乎并不是特定于JPA的错误。 Order是SQL保留的关键字。这些特定的@JoinColumn注释

@JoinColumns({
    @JoinColumn(name = "outlet_id"),
    @JoinColumn(name = "product_id"),
})

在Eclipse中给我一个验证错误。

  

有多个联接列时必须指定引用列名

输出。

Hibernate: create table OrderOutletProduct (order_id bigint not null, outletProduct_outlet_id bigint not null, outletProduct_product_id bigint not null, primary key (order_id, outletProduct_outlet_id, outletProduct_product_id))
Hibernate: create table Orders (id bigint generated by default as identity (start with 1), primary key (id))
Hibernate: create table Outlet (id bigint generated by default as identity (start with 1), primary key (id))
Hibernate: create table OutletProduct (outlet_id bigint not null, product_id bigint not null, primary key (outlet_id, product_id))
Hibernate: create table Product (id bigint generated by default as identity (start with 1), primary key (id))
Hibernate: alter table OrderOutletProduct add constraint FK31ytkakdnwf3mvw7p6paij7u6 foreign key (order_id) references Orders
Hibernate: alter table OrderOutletProduct add constraint FKjsywutttlonx76evhm9b0kk02 foreign key (outletProduct_outlet_id, outletProduct_product_id) references OutletProduct
Hibernate: alter table OutletProduct add constraint FKi0nyyoj3d031g0sn6gkutbxn5 foreign key (outlet_id) references Outlet
Hibernate: alter table OutletProduct add constraint FKr3s09f6ofstlb1qomfwfjsjwy foreign key (product_id) references Produc

因此,我建议从此处开始并慢慢添加内容,以确保您了解注释的作用方式,直到您对遇到的任何错误或问题更具体为止。