Reputation: 1260
I have a situation where I have an entity VCenterDistributedVirtualPortgroup which extends VCenterNetwork and both entities are in a OneToMany relationship inside the entity VCenterFolder. I'm getting the following error:
Caused by: org.h2.jdbc.JdbcSQLException: NULL not allowed for column "NETWORK_TYPE"; SQL statement: insert into folder_network (folder_type, folder_val, distributedVirtualPortgroups_type, distributedVirtualPortgroups_val) values (?, ?, ?, ?) [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;}
....
}
This results in a join table that looks like the following:
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
I'm new to JPA, but my guess is that a join table is needed for both VCenterFolder-VCenterNetwork and VCenterFolder-VCenterDistributedVirtualPortgroup, but since VCenterDistributedVirtualPortgroup extends VCenterNetwork, it's building one join table with both relations but using a different type/val pair for each relation. I would assume that only one pair will be used at a time with the other being null. That seems to be a problem. It would seem to me that the fields should either be nullable or the two sets of type/val pairs should be merged into one.
I assume there is some way round this, but I sure don't know what it is.
Upvotes: 1
Views: 936
Reputation: 1260
MOR happens to have the members type & val, thus the names in the join table.
I solved the problem by adding the folloing JoinTable on both the network and distributedVirtualPortgroups fields:
@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")}
)
Upvotes: 2