6 Replies Latest reply on Jan 13, 2017 9:29 AM by vladsz83

    JPA Storage: Persistence unit not found :(

    vlads27

      Hi,

       

      Can anyone help me please to solve a persistence problem. I have a project with configured and well-working persistence-unit. I'm trying to configure read- and write- behind feature for my cache. I took the simplest configuration than I found:

       

      ConfigurationBuilder configurationBuilder = ...;

       

      1. configurationBuilder.persistence()

      .addStore(JpaStoreConfigurationBuilder.class)

        .persistenceUnitName("myUnitName")

        .entityClass(MyData.class);

       

      Although, deep inside the cache initialization routines an exception is met:

       

      PersistenceException: “Persistence Unit [nyUnitName] not found”

       

      The unit correctly works in the project. EntiryManagers are injected by @PersistenceContext just fine. But in Infinispan, PersistenceMangers and EntityManagerFactoryRegistry can't find the unit. The last tries to find the unit via Persistence.createEntityManagerFactory()

       

      Did I miss something?

       

      Thanks

        • 1. Re: JPA Storage: Persistence unit not found :(
          sebastian.laskawiec

          Could you please tell us more about your deployment? What kind of server are you using? Where do you place persistence.xml?

           

          Also, could you please check if you project properly discovers Persistence Unit by calling Persistence.createEntityManagerFactory(persistenceUnitName).

          • 2. Re: JPA Storage: Persistence unit not found :(
            vladsz83

            Hello, Sebastian!

             

            No, the project can't discover Persistence Unit by calling Persistence.createEntityManagerFactory()

             

            I deploy a war-file on Tomcat9 running with JVM1.8 The DataSource is configured in the tomcat\conf\context.xml with <Resource ... /> and <ResourceLink ... />. The ojdbc-driver is placed in tomcat\lib. The jpa provider is EclipseLink.

             

            I do not use persistence.xml. All the persistence-related things are source-configured instead of xml-variant. The code clipping:

             

            @Bean
            JpaVendorAdapter jpaVendorAdapter(...) {

               final EclipseLinkJpaVendorAdapter jpaVendorAdapter = new EclipseLinkJpaVendorAdapter();

              ...

               return jpaVendorAdapter;

            }

             

            @Bean
            DataSource dataSource(JndiObjectFactoryBean jndi) {

               return ...;

            }

             

            @Bean
            PlatformTransactionManager transactionManager(EntityManagerFactory emf) {

               final JpaTransactionManager transactionManager = new JpaTransactionManager();

              ...

               return transactionManager;

            }

             

             

            @Bean
            LocalContainerEntityManagerFactoryBean entityManagerFactory(

               JpaVendorAdapter jpaVendor,

               DataSource ds

            ) throws Exception {

             

               LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();

             

              emf.setJpaVendorAdapter(jpaVendor);

              emf.setDataSource(ds);

             

               Map<String, String> jpaProperties = new HashMap<>();

              jpaProperties.put("eclipselink.logging.level", "SEVERE");

              jpaProperties.put("eclipselink.logging.parameters", "true");

              jpaProperties.put("eclipselink.weaving", "static");

              jpaProperties.put("eclipselink.jdbc.batch-writing", "Oracle-JDBC");

            ...

             

              emf.setJpaPropertyMap(jpaProperties);

             

              emf.setPersistenceProviderClass(org.eclipse.persistence.jpa.PersistenceProvider.class);

             

              emf.setPackagesToScan(

            ...

               );

             

              emf.setPersistenceUnitName("myUnitName");

             

               return emf;

            }

            • 3. Re: JPA Storage: Persistence unit not found :(
              sebastian.laskawiec

              Unfortunately it seems you the Spring + EclipseLink integration bypasses persistence API somehow (this is why Persistence.createEntityManagerFactory() returns null or throws an exception).

               

              Infinispan JPA implementation uses Persistence API (see this part) to extract EntityManagerFactory. So I believe you have two choices at this point:

              1. Refactor you project to use persistence.xml and make Persistence.createEntityManagerFactory() method to return proper EntityManagerFactory. I would suggest you to take this path.
              2. Implement a custom JPA Cache Store which will use your integration bits (you might even fork our JPA Cache Store)
              1 of 1 people found this helpful
              • 4. Re: JPA Storage: Persistence unit not found :(
                vladsz83

                Understood. Thanks again. I like 2nd variant.

                 

                Few questions left:

                1. Is there an example how to configure my own sink/writer and probably the modifications queue? We don’t know now which writer would be better and are thinking of a custom highly tuned one, maybe of JDBC templates implementation. We'd like just to put our CacheStore into a general persistence configuration.
                2. In case of async storing, where and how the modifications queue is kept? Let’s suppose we got a replicated/distributed cache allocated on several nodes. What if current active node crashes? I mean the node which is modifying cache at the moment. Will the enqueued cache modifications be replicated and stored from another node?
                3. Is there any batching? I see some attempts in the implementation code, but there are no calls like saveAll(), saveBatch(), loadBatch(), etc. in CacheLoader/CacheWritte
                • 5. Re: JPA Storage: Persistence unit not found :(
                  ryanemerson
                  1. Is there an example how to configure my own sink/writer and probably the modifications queue? We don’t know now which writer would be better and are thinking of a custom highly tuned one, maybe of JDBC templates implementation. We'd like just to put our CacheStore into a general persistence configuration.

                   

                  To configure your own writer, you will want to extend AbstractStoreConfiguration or AbstractJdbcStoreConfiguration if you want to use the Infinispan ConnectionFactory as well as their respective builder implementations (AbstractStoreConfigurationBuilder, AbstractJdbcStoreConfigurationBuilder).  You should then be able to pass your custom builder class as part of the normal cache configuration and configure the modification size the same as with an Infinispan provided store, e.g.:

                   

                  new ConfigurationBuilder()
                    .persistence()
                    .addStore(CustomConfigurationBuilder.class)
                    .async()
                    .modificationQueueSize(1024)
                    .build();
                  

                   

                   

                  In case of async storing, where and how the modifications queue is kept? Let’s suppose we got a replicated/distributed cache allocated on several nodes. What if current active node crashes? I mean the node which is modifying cache at the moment. Will the enqueued cache modifications be replicated and stored from another node?

                  If the "active" node crashes after it has finished replicating the operation to a backup, then the backup will add the operation to it's own modifications-queue and eventually execute it. However, if the active node crashes during replication then it is possible that the backup will also miss this operation. Note, for this to work the store cannot be configured as "Shared" or "Singleton"

                   

                  Is there any batching? I see some attempts in the implementation code, but there are no calls like saveAll(), saveBatch(), loadBatch(), etc. in CacheLoader/CacheWritte

                  Currently (Infinispan 9.x) the only way to write in batches is by implementing the TransactionalCacheWriter, however this also requires the cache to be transactional and for the store's transactional attribute to be enabled. Long term we intend to provide batching support for non-transactional caches (See [ISPN-5218]).

                  1 of 1 people found this helpful
                  • 6. Re: JPA Storage: Persistence unit not found :(
                    vladsz83

                    Got it.

                    There are a bit more to re-implement than expected. And unfortunately to me, it is unacceptable to have a chance to lose data to be stored.

                    Anyway, thanks a lot, Ryan.