Call Hazelcast Map to use Transaction from EJB client (Web Application) not work

92 views
Skip to first unread message

Cidy Long

unread,
Aug 26, 2021, 12:14:53 AM8/26/21
to Payara Forum
Environment: 

Payara 5.2021.5 community edit, 
OS: Centos 8

I'm trying to access Hazelcast map from Web Application.

1. Entity bean JPA persistence.xml as:
......
<persistence-unit name="PG12_OZSSC_JTAPU" transaction-type="JTA">
   <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
   <jta-data-source>jdbc/PG12_ozssc_105</jta-data-source>
   <class>com.longz.thss.jpa.entity.Abn</class>
   <class>com.longz.thss.jpa.entity.Address</class>
......
<properties>
</properties>
</persistence-unit>
2. Hazelcast map MapStore coded with:
......
private static final String JTA_PU_NAME = "PG12_OZSSC_JTAPU";

   @PersistenceUnit(unitName = JTA_PU_NAME)
   private EntityManagerFactory emf;
   @PersistenceContext(unitName = JTA_PU_NAME)
   private EntityManager em;
@Override
public synchronized void store(String s, Address address) {
   if(!em.isJoinedToTransaction()){
           em.joinTransaction();
   }
       storeEntityToDB(address);
       em.flush();
}
protected void storeEntityToDB(Address entity){
       Address exist = em.find(Address.class,entity.getAddressId());
       if (exist != null){
           if (!entity.equals(exist)){
               em.merge(entity);
           }
       }else{
           em.persist(entity);
       }
   }
......
3. map configure in hazelcast-config.xml as
......
<map name="address">
       <time-to-live-seconds>5400</time-to-live-seconds>
       <max-idle-seconds>3600</max-idle-seconds>
       <in-memory-format>OBJECT</in-memory-format>
       <backup-count>1</backup-count>
       <async-backup-count>0</async-backup-count>
       <read-backup-data>true</read-backup-data>
       <map-store enabled="true" initial-mode="EAGER">
           <class-name>com.longz.thss.jpa.mapstore.AddressMapStore</class-name>
           <write-delay-seconds>0</write-delay-seconds>
           <!-- <write-batch-size>100</write-batch-size> -->
           <write-coalescing>false</write-coalescing>
       </map-store>
   </map>
......
4. map access by load(),loadAll() etc. over hazelcast instance properly

5. Build a EJB module with remote interface, and implements the remote
- Remote interface as:
......
@Remote
public interface AddressRemote {
   void save(Address address);
   void remove(Address address);
}
......
- Remote impleements as:
......
@Remote(AddressRemote.class)
@Startup
@Singleton(name = "addressEJB",mappedName = "EJBModule-EJB-addressEJB")
public class AddressRemoteImpl implements AddressRemote, Serializable {
......
@PostConstruct
   public void init(){
       if(hzInstance != null){
           addressMap = hzInstance.getMap(ADDRESS_MAP_NAME);
       }
   }
@Override
   public void save(Address address) {
       if(addressMap != null){
           addressMap.put(address.getAddressId(),address);
       }else{
           try {
               throw new NotFoundException("Address Map not fund from Address EJB implementation.");
           } catch (NotFoundException e) {
               e.printStackTrace();
           }
       }
   }
......
}
5. When I tried to call the EJB services from Web Applicaiton
JSF web controller as:
@Named(value = "addressHostWebController")
@SessionScoped
@DependsOn("geoPlaceEJB")
public class AddressHostWebController implements Serializable {
.......
public String saveEntity(){
       addressRemote.save(addressBean.getCurrentAddress());
       addressBean.findAll();
       return LIST_ADDRESS;
   }
.......
}
when call controller's save()function to save an address to map
(As hazelcast-config.xml defined, the once map entry was updated, Hazelcast will write through to database straight way)
But, unfortunately, javax.persistence.TransactionRequiredException: throws as:
[2021-08-26T11:18:18.051+1000] [Payara 5.2021.5] [WARNING] [] [javax.enterprise.web] [tid: _ThreadID=100 _ThreadName=http-thread-pool::http-listener-1(3)] [timeMillis: 1629940698051] [levelValue: 900] [[
 StandardWrapperValve[Faces Servlet]: Servlet.service() for servlet Faces Servlet threw exception
javax.persistence.TransactionRequiredException: 
Exception Description: No externally managed transaction is currently active for this thread
at org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.throwCheckTransactionFailedException(JTATransactionWrapper.java:96)
.......
Seems, save() function caller (web application) not enabled to use JPA's entityManager's transactions? or I had some persistence.xml configure missed? or some thing else?
Reply all
Reply to author
Forward
0 new messages