JPA many to many (with extra col) not working with Infinispan JPA cache store
rajivpatil Feb 12, 2018 6:00 AMHi
I am pretty new to JPA.
I have two entity tables Groups & Rules and an association table Group_Rule which contains many to many mapping of Groups & Rules.
In my application I am storing the Groups & Rules in infinispan embedded cache (REPL_SYNC, preload=true) , I have two caches one for Groups
and another one for Rules.
Based on articles I read over internet, i created JPA entities to model this relationship. Everything works fine when I test directly with hibernate
i.e. manually create EntitiyManager, begin & commit transaction. ( I am able to perfrom CRUD operations on Groups & Rules, I am able to add Rule to Group and remove Rule from Group. I am also able to delete a rule or group and keep the association table in sync.)
However when i plug-in Infinispan cache with JPACachestore and route my operations via infinispan, some of my test cases fail
1. When i delete Rule, it gets deleted from Rule Cache but in the underlying Rule table & Group_Rule table the row is not deleted, in the logs i dont see hibernate generate delete statement
2. When i delete Group, it gets deleted from Group Cache but in the underlying Group table & Group_Rule table the row is not deleted
3. When i delete a Rule from Group, it gets correctly reflected in Group_Rule table, similarly when I add a rule to group it gets correctly reflected in Group_Rule table.
Here is my set-up
1. Infinispan - 9.1.4 , JPACacheStore, shared true, preload true
2. Apache Derby 10.14.1.0 (network mode)
3. jdk 1.8.40
Group class
@Id
@Column(name="ID")
private long Id;
@OneToMany(mappedBy="group",cascade=CascadeType.ALL,orphanRemoval = true)
private Set<GroupRule> groupRules = new HashSet<GroupRule>(0);
getter/setter
GroupRule Class with @IdClass(GroupRuleId.class
@Id
private long group_Id;
@Id
private long rule_Id;
@ManyToOne
@JoinColumn(name="GROUP_ID", updatable=false, insertable=false)
private Group group;
@ManyToOne
@JoinColumn(name="RULE_ID", updatable=false, insertable=false)
private Rule rule;
... getter / setter
GroupRuleId Class (Embeddable)
private long group_Id;
private long rule_Id;
...getter / setter
Rule Class
@Id
@Column(name="ID")
private long Id;
other fields
..getter / setters
persistence.xml
<persistence-unit name="RULES" transaction-type="RESOURCE_LOCAL">
<class>xx.BaseRuleEntity</class>
<class>xx.Rule</class>
<class>xx.Group</class>
<class>xx.GroupRule</class>
<class>xx.GroupRuleId</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/rulesdb" />
<property name="javax.persistence.jdbc.user" value="" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="javax.persistence.schema-generation.database.action" value="none"/>
</properties>
</persistence-unit>
<persistence-unit name="GROUPS" transaction-type="RESOURCE_LOCAL">
<class>xx.BaseRuleEntity</class>
<class>xx.Rule</class>
<class>xx.Group</class>
<class>xx.GroupRule</class>
<class>xx.GroupRuleId</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/rulesdb" />
<property name="javax.persistence.jdbc.user" value="" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="javax.persistence.schema-generation.database.action" value="none"/>
</properties>
</persistence-unit>
Cache
this.cacheMgr = new DefaultCacheManager(
GlobalConfigurationBuilder.defaultClusteredBuilder()
.transport().nodeName(System.getProperty("NodeName"))
.build());
Configuration ruleCacheConfig = new ConfigurationBuilder().clustering()
.cacheMode(CacheMode.REPL_SYNC)
.persistence().passivation(false)
.addStore(JpaStoreConfigurationBuilder.class)
.purgeOnStartup(false).shared(true)
.persistenceUnitName(RULES)
.entityClass(Rule.class)
.storeMetadata(false)
.preload(true)
.build();
Configuration ruleGrpCacheConfig = new ConfigurationBuilder().clustering()
.cacheMode(CacheMode.REPL_SYNC)
.persistence().passivation(false)
.addStore(JpaStoreConfigurationBuilder.class).purgeOnStartup(false).shared(true)
.persistenceUnitName(GROUPS)
.entityClass(Group.class)
.storeMetadata(false)
.preload(true)
.build();
this.cacheMgr.defineConfiguration(RULES, ruleCacheConfig);
this.cacheMgr.defineConfiguration(GROUPS, ruleGrpCacheConfig);
***********
Pls help !!