Hibernate Envers在主键中包含该列,即使它们不是主表中的键

时间:2018-08-18 15:59:18

标签: java hibernate hibernate-envers

在这种情况下:

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.envers.Audited;

@Entity
@Audited
public class TestEntity implements Serializable {

    @Id
    private Long id;

    @ElementCollection
    private List<String> strings = new ArrayList<>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public List<String> getStrings() {
        return strings;
    }

    public void setStrings(List<String> strings) {
        this.strings = strings;
    }
}

Hibernate将按预期创建两个表:

创建表testentity(   id bigint(20)NOT NULL,   主键(id) )ENGINE = InnoDB DEFAULT CHARSET = utf8;

创建表testentity_strings(   TestEntity_id bigint(20)NOT NULL,   strings varchar(255)默认为空,   键FK6gvnp6uhj6p14qb8jr7w4a4scTestEntity_id),   约束FK6gvnp6uhj6p14qb8jr7w4a4sc外键(TestEntity_id)参考testentityid) )ENGINE = InnoDB DEFAULT CHARSET = utf8;

Envers还会创建两个表:

创建表testentity_aud(   id bigint(20)NOT NULL,   revision int(11)NOT NULL,   action tinyint(4)缺省为NULL,   主键(idrevision),   键FKtoml4ns3581arnt5f7i1srxairevision),   约束FKtoml4ns3581arnt5f7i1srxai外键(revision)参考revinfoREV) )ENGINE = InnoDB DEFAULT CHARSET = utf8;

创建表testentity_strings_aud(   revision int(11)NOT NULL,   TestEntity_id bigint(20)NOT NULL,   strings varchar(255)NOT NULL,   action tinyint(4)缺省为NULL,   主键(revisionTestEntity_idstrings),   约束FKadlc041c3dxra6fmfxsku0fuh外键(revision)参考revinfoREV) )ENGINE = InnoDB DEFAULT CHARSET = utf8;

问题出在第二个审核表(testentity_strings)上。即使在主表中字符串允许为null,它也会对列“ strings”设置约束(NOT NULL)。

我的业务要求是允许使用空字符串。如何在转义时覆盖此行为?

2 个答案:

答案 0 :(得分:0)

最简单的答案是你不能。

Envers不会像对待ORM一样对待元素集合。相反,Envers为该元素集合构造一个完全独立的实体映射,并通过HBM将所述映射提供给ORM。

我们这样做有两个原因,但是主要原因是它允许用户配置映射,以便可以在哪里审计元素集合,而对拥有实体的其余部分则不行。另外,由于我们提供的映射是此处用于集合的实体映射,因此HBM要求我们必须为其提供ORM主键配置。

从Envers的角度来看,我们不可能从主键中排除字符串值,因为集合中将有多个与同一修订版号相关联的值,因此某些值必须相应地区分表中的不同行。

也就是说,我唯一能看到的解决方法是使用@OneToMany并将您的字符串包装在带有生成ID而不是@ElementCollection的实际实体映射中(如果需要审计值) 。

如果您认为这些值不值得审计,则可以将@NotAudited放在元素集合上,从而也可以绕过该问题。

答案 1 :(得分:0)

Nanos-是否有可能将order-column(如果提供)用作主键而不是element-value,因为这也是我项目的源点。 谢谢