Dreamer
Dreamer

Reputation: 7551

JPA issue on Websphere -- works fine on Tomcat

I have a Spring 3 application using openJPA as persistence management, following section works fine in STS/Tomcat

@Transactional
createBalance(){
.....
    Balance balance = new SummaryBalance();
    balance.setName(name);
    balance.setCurrency(currency);
    balance.setClosingTimestamp(closingTime);
    balance.setStatus(BalanceStatus.OPEN);
    balance.persist(); // persist !!
 ......

    balance.setCloseAmount(amount);
    balance.setLastUpdateTimestamp(now);
}

However, when deploying same code in websphere 7, the closeAmount and lastUpdate does not update(both fields in DB didn't get update but from log both field can return values by their getter) then show up as null, but changes to other fields before persist() do take effect when the method finished. So I bet when the method finishing WS didn't flush the changes towards these fields.

I thought the JPA(regardless of vendor) should keep the balance entity object managed after persist() and flush the object after the method is finished with later changes. Turns out Websphere 7 doesn't make it. Even I put a merge() method

    balance.setCloseAmount(amount);
    balance.setLastUpdateTimestamp(now);
    balance.merge();

still does not help.

Questions:

  1. OpenJPA has already been included as dependencies in the deployment, but why still websphere need to involve with the JPA management?
  2. How to solve the problem?

Thanks in advance.

Upvotes: 2

Views: 927

Answers (2)

Dreamer
Dreamer

Reputation: 7551

Figure out a solution myself with guess work. Simply just place the persist() by the end of the whole method body.

@Transactional
createBalance(){
.....
    Balance balance = new SummaryBalance();
    balance.setName(name);
    balance.setCurrency(currency);
    balance.setClosingTimestamp(closingTime);
    balance.setStatus(BalanceStatus.OPEN);
 ......

    balance.setCloseAmount(amount);
    balance.setLastUpdateTimestamp(now);
 ......
    balance.persist(); // persist !!
}

That can make sure every fields are set before the method finished. Both merge() and explicit flush() won't do the job but only with above compromise. Still not quite sure about the official work around....

I will keep this thread open for any new thinking come in :)

Upvotes: 0

Boris Treukhov
Boris Treukhov

Reputation: 17774

I'm not sure that this exactly answers your question, but I think you should do some reconfiguration to use WebSphere capabilities, please check Spring 3.1 documentation

11.8.1 IBM WebSphere

On WebSphere 6.1.0.9 and above, the recommended Spring JTA transaction manager to use is WebSphereUowTransactionManager. This special adapter leverages IBM's UOWManager API, which is available in WebSphere Application Server 6.0.2.19 and later and 6.1.0.9 and later. With this adapter, Spring-driven transaction suspension (suspend/resume as initiated by PROPAGATION_REQUIRES_NEW) is officially supported by IBM!

and

11.9.1 Use of the wrong transaction manager for a specific DataSource

Use the correct PlatformTransactionManager implementation based on your choice of transactional technologies and requirements. Used properly, the Spring Framework merely provides a straightforward and portable abstraction. If you are using global transactions, you must use the org.springframework.transaction.jta.JtaTransactionManager class (or an application server-specific subclass of it) for all your transactional operations. Otherwise the transaction infrastructure attempts to perform local transactions on resources such as container DataSource instances. Such local transactions do not make sense, and a good application server treats them as errors.

Upvotes: 1

Related Questions