3 Replies Latest reply on Feb 27, 2018 10:37 AM by galder.zamarreno

    JPA many to many (with extra col) not working with Infinispan JPA cache store

    rajivpatil

      Hi

      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 !!