In our codebase, we use xml file for mapping entities to tables. This was created back in 2010.
Eventually for some of our one-to-many relationship b/w entities we introduced a wrapper over PersistentSet.
One such instance where two entities, ConfigContainer.java
and Config.java
are related by one-to-many association:
<class name="org.namespace.ConfigContainer"
table="CONFIG_CONTAINERS">
<id name="id" column="CONFIG_CONTAINER_ID">
<generator class="native"/>
</id>
<version name="optimisticLockVersion"
column="OPTIMISTIC_LOCK_VERSION"
type="long"/>
<property name="configType" column="CONFIG_TYPE" not-null="true" unique="true"/>
<!-- Configs are saved via cascade but are deleted explicitly. -->
<set name="configsForDb" inverse="true" cascade="save-update,merge,persist">
<key column="CONFIG_CONTAINER_ID"/>
<one-to-many class="org.namespace.Config"/>
</set>
<property name="configGeneration" column="CONFIG_GENERATION" not-null="true"/>
</class>
<class name="DbConfig" table="CONFIGS">
<id name="id" column="CONFIG_ID">
<generator class="native"/>
</id>
<version column="OPTIMISTIC_LOCK_VERSION" name="optimisticLockVersion" type="long" />
<many-to-one name="configContainer"
column="CONFIG_CONTAINER_ID"
class="org.namespace.DbConfigContainer"
foreign-key="FK_CONFIG_CONFIG_CONTAINER"
index="IDX_CONFIG_CONFIG_CONTAINER"/>
</class>
POJO for ConfigContainer.java is :
public class ConfigContainer {
private Wrapper<Config> configs = new Wrapper<Config>(Sets.<DbConfig> newHashSet());
/**
* Hibernate uses this to pass in a PersistentSet object (which
* loads things lazily. We wrap it a bit, but make sure to give
* back the original object, too.
*/
public void setConfigsForDb(Set<Config> configs) {
this.configs = new Wrapper<Config>(configs);
}
public Set<DbConfig> getConfigsForDb() {
return configs.delegate();
}
}
The above Wrapper.java
is basically a cache which stores the configs. I can more info if you want.
We are currently facing Performance issues 1.
We want to ask the above problem in this community again. So we are first creating a dummy project modelling such entities. But this time we are using Annotations instead of xml for mapping.
Here is ConfigContainer.java in our dummy project using Annotations.
@Entity
@Table(name = "CONFIG_CONTAINERS")
public class ConfigContainer {
@OneToMany(cascade=CascadeType.ALL, mappedBy="configContainer")
private Wrapper<DbConfig> configs =
new Wrapper<>(new HashSet<DbConfig>());
public void setConfigsForDb(Set<Config> configs) {
this.configs = new Wrapper<>(configs);
}
public Set<Config> getConfigsForDb() {
return configType.delegate;
}
}
But when I run the code, the following exceptions were thrown:
org.namespace.Wrapper collection type not supported for property: org.namespace.ConfigContainer.configs
Custom type does not implement UserCollectionType: org.namespace.Wrapper
I know the solution is to make the Wrapper.java
implement UserCollectionType
2
My question is, why I am not getting the same error in my actual codebase ? In actual codebase, the Wrapper.java
class doesn’t implement UserCollectionType
. Also I have grep-ed my entire codebase but didn’t find any usages of UserCollectionType
. How is it working in xml based mapping.
Hibernate-version: 5.4.27.Final