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?