3 Replies Latest reply on May 25, 2007 9:57 AM by Brian Stansberry

    EJB3 + JBossCache, accessing from external client

    anglor varoa Newbie

      Hi, I've set up a jboss server with a few EJBs and JBoss cache running on the same server. My persistence.xml is deployed with the following options

      <property name="hibernate.cache.use_second_level_cache">true</property>
      <property name="hibernate.cache.use_query_cache">true</property>
      <property name="hibernate.cache.provider_class">org.hibernate.cache.TreeCacheProvider</property>

      and one of my entity beans has the following annotations

      @Table(name = "album", uniqueConstraints = {...}) @Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)

      Everything starts up correctly, no error messages etc.

      I now use some SLSBs to get Entity beans etc. from an external client, which is a standalone java app, and I am expecting the the server side to use the cache as configured, but it's not working as I'd expect.

      First my client complains that

      Exception in thread "main" org.hibernate.HibernateException: Could not instantiate cache implementation
       at org.hibernate.cache.CacheFactory.createCache(CacheFactory.java:64)
       at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:214)
       at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1218)
       at fm.last.catalogue.test.TestClient.<init>(TestClient.java:62)
       at fm.last.catalogue.test.TestClient.main(TestClient.java:251)
      Caused by: org.hibernate.cache.NoCachingEnabledException: Second-level cache is not enabled for usage [hibernate.cache.use_second_level_cache | hibernate.cache.use_query_cache]
       at org.hibernate.cache.NoCacheProvider.buildCache(NoCacheProvider.java:21)
       at org.hibernate.cache.CacheFactory.createCache(CacheFactory.java:61)
       ... 4 more

      The only references i've found about this indicate that you need to include those three lines above to the hibernate.cfg.xml file in the client side. So i do so. And now everything works.


      I don't see any sign that caching is actually happening on the server. I get these messages in my client log (saying there are no other members in the cluster etc.) and the server remains absolutely silent. Which makes me think i've just created a cache in the client, which is not what i want.

      What am i configuring wrong?

      (below is a section of the trace from the client, and the mbean for EJB3EntityTreeCache as deployed in the server)

      Many thanks.

      GMS: address is syphillis:35418
      18:18:50,293 DEBUG FD_SOCK:84 - determinePingDest()=null, pingable_mbrs=[]
      18:18:50,293 DEBUG FD_SOCK:84 - pinger thread terminated
      18:18:52,298 DEBUG PING:84 - initial mbrs are []
      18:18:52,299 DEBUG ClientGmsImpl:84 - initial_mbrs are []
      18:18:52,300 DEBUG ClientGmsImpl:84 - no initial members discovered: creating group as first member
      18:18:52,307 DEBUG GMS:84 - [local_addr=syphillis:35418] view is [syphillis:35418|0] [syphillis:35418]
      18:18:52,310 DEBUG STABLE:84 - stable task started; num_gossip_runs=3, max_gossip_runs=3
      18:18:52,311 DEBUG FD_SOCK:84 - VIEW_CHANGE received: [syphillis:35418]
      18:18:52,312 DEBUG FD_SOCK:84 - first member; cache is empty
      18:18:52,311 INFO TreeCache:94 - TreeCache local address is syphillis:35418
      18:18:52,312 INFO TreeCache:94 - viewAccepted(): [syphillis:35418|0] [syphillis:35418]
      18:18:52,317 DEBUG GMS:84 - syphillis:35418 changed role to org.jgroups.protocols.pbcast.CoordGmsImpl
      18:18:52,317 DEBUG GMS:84 - syphillis:35418 changed role to org.jgroups.protocols.pbcast.CoordGmsImpl
      18:18:52,318 DEBUG ClientGmsImpl:84 - created group (first member). My view is [syphillis:35418|0], impl is org.jgroups.protocols.pbcast.CoordGmsImpl
      18:18:52,353 DEBUG TreeCache:301 - Started TreeCache

      <?xml version="1.0" encoding="UTF-8"?>
       <!-- ==================================================================== -->
       <!-- Defines TreeCache configuration -->
       <!-- ==================================================================== -->
       <mbean code="org.jboss.cache.TreeCache" name="jboss.cache:service=EJB3EntityTreeCache">
       <!-- Configure the TransactionManager -->
       <attribute name="TransactionManagerLookupClass">org.jboss.cache.JBossTransactionManagerLookup</attribute>
       Node locking level : SERIALIZABLE
       REPEATABLE_READ (default)
       <attribute name="IsolationLevel">REPEATABLE_READ</attribute>
       <!-- Valid modes are LOCAL
       <attribute name="CacheMode">REPL_SYNC</attribute>
       <!-- Name of cluster. Needs to be the same for all clusters, in order
       to find each other -->
       <attribute name="ClusterName">EJB3-entity-cache</attribute>
       <attribute name="ClusterConfig">
       <!-- UDP: if you have a multihomed machine,
       set the bind_addr attribute to the appropriate NIC IP address
       <!-- UDP: On Windows machines, because of the media sense feature
       being broken with multicast (even after disabling media sense)
       set the loopback attribute to true
       <UDP mcast_addr="${jboss.partition.udpGroup:}" mcast_port="43333" ip_ttl="2" ip_mcast="true"
       mcast_send_buf_size="150000" mcast_recv_buf_size="80000" ucast_send_buf_size="150000"
       ucast_recv_buf_size="80000" loopback="false" />
       <PING timeout="2000" num_initial_members="3" up_thread="false" down_thread="false" />
       <MERGE2 min_interval="10000" max_interval="20000" />
       <FD shun="true" up_thread="true" down_thread="true" />
       <VERIFY_SUSPECT timeout="1500" up_thread="false" down_thread="false" />
       <pbcast.NAKACK gc_lag="50" max_xmit_size="8192" retransmit_timeout="600,1200,2400,4800" up_thread="false"
       down_thread="false" />
       <UNICAST timeout="600,1200,2400" window_size="100" min_threshold="10" down_thread="false" />
       <pbcast.STABLE desired_avg_gossip="20000" up_thread="false" down_thread="false" />
       <FRAG frag_size="8192" down_thread="false" up_thread="false" />
       <pbcast.GMS join_timeout="5000" join_retry_timeout="2000" shun="true" print_local_addr="true" />
       <pbcast.STATE_TRANSFER up_thread="false" down_thread="false" />
       <!-- The max amount of time (in milliseconds) we wait until the
       initial state (ie. the contents of the cache) are retrieved from
       existing members in a clustered environment
       <attribute name="InitialStateRetrievalTimeout">5000</attribute>
       <!-- Number of milliseconds to wait until all responses for a
       synchronous call have been received.
       <attribute name="SyncReplTimeout">10000</attribute>
       <!-- Max number of milliseconds to wait for a lock acquisition -->
       <attribute name="LockAcquisitionTimeout">15000</attribute>
       <!-- Name of the eviction policy class. -->
       <attribute name="EvictionPolicyClass">org.jboss.cache.eviction.LRUPolicy</attribute>
       <!-- Specific eviction policy configurations. This is LRU -->
       <attribute name="EvictionPolicyConfig">
       <attribute name="wakeUpIntervalSeconds">5</attribute>
       <!-- Cache wide default -->
       <region name="/_default_">
       <attribute name="maxNodes">5000</attribute>
       <attribute name="timeToLiveSeconds">1000</attribute>
       <region name="/clusterstore/ejb/Album">
       <attribute name="maxNodes">10000</attribute>
       <attribute name="timeToLiveSeconds">5000</attribute>
       <region name="/AlbumSearch">
       <attribute name="maxNodes">1000</attribute>
       <attribute name="timeToLiveSeconds">5000</attribute>

        • 1. Re: EJB3 + JBossCache, accessing from external client
          Brian Stansberry Master

          On the server side, use

          <property name="hibernate.cache.provider_class">org.jboss.ejb3.entity.TreeCacheProviderHook</property>

          That provider knows how to talk to the jboss.cache:service=EJB3EntityTreeCache service.

          The only references i've found about this indicate that you need to include those three lines above to the hibernate.cfg.xml file in the client side. So i do so. And now everything works.

          It's not clear to me from your post whether you want second-level caching on the client side.

          1) If you do, sound's like it's at least semi working. You just need to be sure that the JBoss Cache configuration on the client side matches the one on the server side.

          2) If you don't, include this in your hibernate.cfg.xml:

          <property name="hibernate.cache.use_second_level_cache">false</property>
          <property name="hibernate.cache.use_query_cache">false</property>

          Hibernate defaults to 'true' on 'use_second_level_cache' so if you mark any of your entities as cacheable it will throw the exception you posted when you don't configure a provider. Explicitly setting the config to false should get around the problem.

          • 2. Re: EJB3 + JBossCache, accessing from external client
            anglor varoa Newbie

            It works perfectly.

            No, I didn't really need second level cache, I was just adding it to keep it as similar as I could to the examples I had.

            Will I need to use that client-side cache if I use query cache or will it stay in the server if I enable it?


            • 3. Re: EJB3 + JBossCache, accessing from external client
              Brian Stansberry Master

              Glad it's working. :)

              As for the query cache, if you set it to true on the client side, then you are going to have to set up JBoss Cache as the second level cache on the client side.

              I was briefly thinking maybe you could get away with using some other cache provider (ehcache, etc.) on the client side for your query caching, but the problem is if the client side case isn't a cluster-aware one that knows how to communicate with the server side cache you could get this:

              1) Do a query on the client side that returns beans A, B, C. Cache the result.

              2) Do something on the server side that changes B such that it would no longer match the query.

              3) Do the query again on the client side. Client side query caching layer doesn't know about the change to B, so the out-of-date cached result of A, B, C is returned. Invalid.

              Same problem applies in reverse as well.