【问题标题】:null not allowed for column in join table with one entity extending another一个实体扩展另一个实体的连接表中的列不允许为 null
【发布时间】:2015-02-04 05:55:33
【问题描述】:

我有一个实体 VCenterDistributedVirtualPortgroup 扩展了 VCenterNetwork,并且这两个实体在实体 VCenterFolder 内处于 OneToMany 关系中。我收到以下错误:

原因:org.h2.jdbc.JdbcSQLException: NULL not allowed for column "NETWORK_TYPE"; SQL 语句: 插入到 folder_network (folder_type、folder_val、distributedVirtualPortgroups_type、distributedVirtualPortgroups_val) 值 (?, ?, ?, ?) [23502-182]

VCenterNetwork:

@Entity
@Embeddable
@Table(name="network")
@DiscriminatorColumn(name="discriminator")
@DiscriminatorValue("Network")
public class VCenterNetwork
{
    @Transient
    private Network network;

    @Transient
    private static Map<MOR, VCenterNetwork> networkMap = new TreeMap<MOR, VCenterNetwork>();

    @EmbeddedId
    private MOR id;
    public MOR getId() {return this.id;}
    public void setId(MOR id) {this.id = id;}
    ...
}

VCenterDistributedVirtualPortgroup:

@Entity
@Table(name="distributedvirtualportgroup")
@DiscriminatorColumn(name="discriminator")
@DiscriminatorValue("DistributedVirtualPortgroup")
public class VCenterDistributedVirtualPortgroup extends VCenterNetwork
{
    @Transient
    private DistributedVirtualPortgroup distributedVirtualPortgroup;

    @Transient
    private static Map<MOR, VCenterDistributedVirtualPortgroup> distributedVirtualPortgroupMap = new TreeMap<MOR, VCenterDistributedVirtualPortgroup>();
    ...
}

VCenterFolder:

@Entity
@Table(name="folder")
public class VCenterFolder
{
    @Transient
    private Folder folder;

    @Transient
    private static Map<MOR, VCenterFolder> folderMap = new TreeMap<MOR, VCenterFolder>();

    @EmbeddedId
    private MOR id;
    public MOR getId() {return this.id;}
    public void setId(MOR id) {this.id = id;}

    @Embedded
    @OneToMany(cascade=CascadeType.ALL)
    private List<VCenterNetwork> network = new ArrayList<VCenterNetwork>();
    public List<VCenterNetwork> getNetwork() {return this.network;}
    public void getvirtualNetwork(List<VCenterNetwork> network) {this.network = network;}

    @Embedded
    @OneToMany(cascade=CascadeType.ALL)
    private List<VCenterDistributedVirtualPortgroup> distributedVirtualPortgroups = new ArrayList<VCenterDistributedVirtualPortgroup>();
    public List<VCenterDistributedVirtualPortgroup> getDistributedVirtualPortgroups() {return this.distributedVirtualPortgroups;}
    public void setDistributedVirtualPortgroups(List<VCenterDistributedVirtualPortgroup> distributedVirtualPortgroups){this.distributedVirtualPortgroups = distributedVirtualPortgroups;}
    ....
}

这会生成如下所示的连接表:

FOLDER_NETWORK
    FOLDER_TYPE - VARCHAR(255) NOT NULL
    FOLDER_VAL - VARCHAR(255) NOT NULL
    NETWORK_TYPE - VARCHAR(255) NOT NULL
    NETWORK_VAL - VARCHAR(255) NOT NULL
    DISTRIBUTEDVIRTUALPORTGROUP_TYPE - VARCHAR(255) NOT NULL
    DISTRIBUTEDVIRTUALPORTGROUP_TYPE - VARCHAR(255) NOT NULL

我是 JPA 的新手,但我的猜测是 VCenterFolder-VCenterNetwork 和 VCenterFolder-VCenterDistributedVirtualPortgroup 都需要一个连接表,但是由于 VCenterDistributedVirtualPortgroup 扩展了 VCenterNetwork,它正在构建一个具有两种关系但使用不同类型的连接表/每个关系的 val 对。我假设一次只使用一对,另一对为空。这似乎是个问题。在我看来,这些字段要么可以为空,要么应该将两组类型/值对合并为一组。

我认为有一些方法可以解决这个问题,但我确实不知道它是什么。

【问题讨论】:

    标签: java jpa


    【解决方案1】:

    MOR 恰好有成员类型 & val,因此是连接表中的名称。

    我通过在网络和分布式虚拟端口组字段上添加以下 JoinTable 解决了这个问题:

        @JoinTable
        (
                name="FOLDER_NETWORK",
                joinColumns= {@JoinColumn(name="TYPE", referencedColumnName="TYPE"), @JoinColumn(name="VAL", referencedColumnName="VAL")},
                inverseJoinColumns= {@JoinColumn(name="NETWORK_TYPE", referencedColumnName="TYPE"), @JoinColumn(name="NETWORK_VAL", referencedColumnName="VAL")}
        )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-18
      • 2019-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多