Cannot update any attribute in the testUpdateBookOrdersShippingAddress - oracle

I have a problem about updating BookOrder. BookOrder is connected to DetailOrder via composite key according to many to many relationship.
The error is shown below.
May 23, 2019 2:33:48 PM com.mchange.v2.c3p0.impl.NewPooledConnection
INFO: [c3p0] Exceptions occurred while trying to close a PooledConnection's resources normally.
May 23, 2019 2:33:48 PM com.mchange.v2.c3p0.impl.NewPooledConnection
INFO: [c3p0] NewPooledConnection close Exception.
java.sql.SQLException: ORA-03106: fatal two-task communication protocol error
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:494)
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:441)
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:436)
at oracle.jdbc.driver.T4C7Ocommoncall.processError(T4C7Ocommoncall.java:86)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:623)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:252)
at oracle.jdbc.driver.T4C7Ocommoncall.doOLOGOFF(T4C7Ocommoncall.java:62)
at oracle.jdbc.driver.T4CConnection.logoff(T4CConnection.java:908)
at oracle.jdbc.driver.PhysicalConnection.close(PhysicalConnection.java:2005)
at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:642)
at com.mchange.v2.c3p0.impl.NewPooledConnection.closeMaybeCheckedOut(NewPooledConnection.java:255)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.destroyResource(C3P0PooledConnectionPool.java:622)
at com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask.run(BasicResourcePool.java:1076)
at com.mchange.v2.resourcepool.BasicResourcePool.destroyResource(BasicResourcePool.java:1101)
at com.mchange.v2.resourcepool.BasicResourcePool.destroyResource(BasicResourcePool.java:1062)
at com.mchange.v2.resourcepool.BasicResourcePool.access$100(BasicResourcePool.java:44)
at com.mchange.v2.resourcepool.BasicResourcePool$5.run(BasicResourcePool.java:1316)
May 23, 2019 2:33:48 PM com.mchange.v2.resourcepool.BasicResourcePool
WARNING: Failed to destroy resource: com.mchange.v2.c3p0.impl.NewPooledConnection#3dd18dc6
java.sql.SQLException: Some resources failed to close properly while closing com.mchange.v2.c3p0.impl.NewPooledConnection#3dd18dc6
at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:664)
at com.mchange.v2.c3p0.impl.NewPooledConnection.closeMaybeCheckedOut(NewPooledConnection.java:255)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.destroyResource(C3P0PooledConnectionPool.java:622)
at com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask.run(BasicResourcePool.java:1076)
at com.mchange.v2.resourcepool.BasicResourcePool.destroyResource(BasicResourcePool.java:1101)
at com.mchange.v2.resourcepool.BasicResourcePool.destroyResource(BasicResourcePool.java:1062)
at com.mchange.v2.resourcepool.BasicResourcePool.access$100(BasicResourcePool.java:44)
at com.mchange.v2.resourcepool.BasicResourcePool$5.run(BasicResourcePool.java:1316)
I think there can be a session problem. Session can be automatically closed when it is needed to open.
My test class
#Test
public void testUpdateBookOrdersShippingAddress() {
Integer orderId = 48;
BookOrders bookorders = ordersDAO.get(orderId);
System.out.println("Update Before (ShippingAddress) : " + bookorders.getShippingAddress());
bookorders.setShippingAddress("New Home Shipping Address");
try {
ordersDAO.update(bookorders);
} catch (Exception e) {
e.printStackTrace();
}
BookOrders updatedOrder = ordersDAO.get(orderId);
System.out.println("Update After (ShippingAddress) : " + updatedOrder.getShippingAddress() );
assertEquals(bookorders.getShippingAddress(), updatedOrder.getShippingAddress());
}
Hibernate Class for get and update method.
public T update(T t) {
Session session = sessionFactory.openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
session.merge(t);
session.flush();
session.getTransaction().commit();
session.close();
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
transaction.rollback();
}
return t;
}
public T get(Class<T> type,Object id) {
Session session = sessionFactory.openSession();
Transaction transaction = null;
T t = null;
try {
transaction = session.beginTransaction();
t = session.get(type, (int)id);
session.flush();
session.getTransaction().commit();
session.close();
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
transaction.rollback();
}
return t;
}

In update function of hibernate class based on generic type, I could use session.update(t); instead of session.merge(t); and I could solve it.

Related

Catch optimistick lock exception hibernate spring boot

i'm trying to intercept an optimistick lock exception and throw another exception but it doesn't work in my case, the exception is catched but i still have error optimistick lock in my console.
//MY DAO
public Entity getEntitieSimple(...) throws CustomException{
Entity entity="my select";
}
//MY SERVICE
#Transactional(propagation = Propagation.REQUIRED, readOnly = true)
public Entity recupererEntity() throws CustomException{
Entity entity =null;
try {
entity = dao.getEntitieSimple(...);
}catch (Exception exec){
throw new CustomException("custom message");
}
return entity;
}
#Transactional(propagation = Propagation.REQUIRED)
public void myUpdate() throws HibernateException{
try {
// entity update here
}catch (HibernateException exec){
log.error("OPTIMISTIC: "+ exec.getMessage());
throw new HibernateException("optimi update");
}
}
I'm getting this error evern after catching the exception:
ERROR - 29-09-2022 09:59:44.204 - http-nio-8090-exec-5 - 3933807 - null - c:96e7d7ca8f7d5637 - org.hibernate.internal.ExceptionMapperStandardImpl - HHH000346: Error during managed flush [Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.apicil.cosy.dop.domain.impl.Entity#1420]]
You have to catch ConcurrencyFailureException
private void updateStatus(UpdateOrderDto dto, OrdersStatusUpdaterService self) {
try {
updateStatusHelper(dto, self);
} catch (ConcurrencyFailureException ex) {
log.error("Concurrent modification error. Will try next time. orderId={}", dto.getId(), ex);
}
}

Spring transaction: unexpected rollback behavior

I am doing a simple experiment for debugging purpose.
First I insert serveral records to database, and then I do a invalid data conversion which will throw DataIntegrityViolationException, but I will catch the exception.
I expected the records being successfully inserted into the db, since I catch the checked exception. But the whole thing is rolled back.
I do the experiment again using TransactionTemplate instead of using annotation, same result.
My questions are:
is this the expected behavior?
If anwser to No.1 is yes, then I catch the exception, how is it possible that spring knows an exception is thrown?
Here is my code:
public void insertValue() {
jdbcTemplate.execute("insert into people (person_id, name) values (4, 'asjkdhadsjkqhweqkewhkashdkahd')");
jdbcTemplate.execute("insert into people (person_id, name) values (5, 'tttqqq')");
}
// this should throw exception
public void truncateValue() {
jdbcTemplate.execute("alter table people alter column name varchar(7)");
}
public void jdbc_calls() {
insertValue();
try {
truncateValue();
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println("Finish");
}
public void run() {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
transactionTemplate.execute(transactionStatus -> {
try {
jdbc_calls();
} catch (RuntimeException e) {
throw e;
} catch (Throwable e) {
throw new RuntimeException(e);
}
return null;
});
}
More about question No.2.
Here is the source code of TransactionTemplate.execute()
From my understanding, if I don't throw an exception, rollbackOnException won'r be triggered.
public <T> T execute(TransactionCallback<T> action) throws TransactionException {
Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");
if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
}
else {
TransactionStatus status = this.transactionManager.getTransaction(this);
T result;
try {
result = action.doInTransaction(status);
}
catch (RuntimeException | Error ex) {
// Transactional code threw application exception -> rollback
rollbackOnException(status, ex);
throw ex;
}
catch (Throwable ex) {
// Transactional code threw unexpected exception -> rollback
rollbackOnException(status, ex);
throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
}
this.transactionManager.commit(status);
return result;
}
}
is this the expected behavior?
Yes, it is.
If anwser to No.1 is yes, then I catch the exception, how is it possible that spring knows an exception is thrown?
When an exception occurs, spring will mark your transaction as rollbackOnly.
So even when you catch your exception, at the end of your method, your transaction still rolled back.
In your case, I don't get why you use #Transaction since you want to commit regardless if exception occurs.
Edit
When you're using transaction with DB, the transaction invocation is delegated to EntityManager.
Look at AbstractEntityManagerImpl#handlePersistenceException:
#Override
public void handlePersistenceException(PersistenceException e) {
if ( e instanceof NoResultException ) {
return;
}
if ( e instanceof NonUniqueResultException ) {
return;
}
if ( e instanceof LockTimeoutException ) {
return;
}
if ( e instanceof QueryTimeoutException ) {
return;
}
try {
markForRollbackOnly();
}
catch ( Exception ne ) {
//we do not want the subsequent exception to swallow the original one
LOG.unableToMarkForRollbackOnPersistenceException(ne);
}
}
When exception occurs, the EntityManager mark your transaction as rollbackOnly before throws out the exception for you to catch.
After the exception is catched in your service, the AbstractPlatformTransactionManager will try to commit (because, as you know, no exception is detected there), but the EntityManager refuses to commit because its detect that the transaction marked as rollback-only.
If you read the exception, you will see something like:
javax.persistence.RollbackException: Transaction marked as rollbackOnly

EJB3.0 transaction fail inside a method in successive transaction taking place

I am processing three transaction inside a single method in stateless container managed bean .i want to persist three transaction while if one throws exception other two should complete their respective transaction ,error is that if first or any one is throwing exception other two are to executing please give some helpful suggestion
public void allocateSubjectToStudent(SubjectAllocatedToStudentDto dto)throws Exception {
logger.info("allocateSubjectToStudent method entry :");
List<Subject> coreList=dto.getCoreList();
Iterator<Subject> iterator=coreList.iterator();
while(iterator.hasNext()){
logger.info("inside while :");
SubjectAllocatedToStudentBo bo=new SubjectAllocatedToStudentBo();
bo.setBacthId(dto.getBacthId());
bo.setSemester(dto.getSemester());
bo.setStudentId(dto.getStudentId());
Subject subject=iterator.next();
bo.setSubjectName(subject.getSubjectName());
bo.setSubjectType(subject.getAbbreviation());
try{
manager.persist(bo);
}
catch(javax.persistence.PersistenceException e){
Throwable t = e.getCause();
while ((t != null) && !(t instanceof org.hibernate.exception.ConstraintViolationException)) {
t = t.getCause();
}//while
if (t instanceof org.hibernate.exception.ConstraintViolationException) {
throw new Exception("Core subject already allocated to student");
} //end of if
}//end of catch
}//end of while
List<Subject> departmentallist=dto.getDepartmentList();
Iterator<Subject> iterator1=departmentallist.iterator();
while(iterator1.hasNext()){
logger.info("inside while :");
SubjectAllocatedToStudentBo bo=new SubjectAllocatedToStudentBo();
bo.setBacthId(dto.getBacthId());
bo.setSemester(dto.getSemester());
bo.setStudentId(dto.getStudentId());
Subject subject=iterator1.next();
bo.setSubjectName(subject.getSubjectName());
bo.setSubjectType(subject.getAbbreviation());
try{
manager.persist(bo);
}
catch(javax.persistence.PersistenceException e){
Throwable t = e.getCause();
while ((t != null) && !(t instanceof org.hibernate.exception.ConstraintViolationException)) {
t = t.getCause();
}//while
if (t instanceof org.hibernate.exception.ConstraintViolationException) {
throw new Exception("InterDepartmental subject already allocated to student");
} //end of if
}//end of catch
}//end of while
List<Subject> electiveList=dto.getElectiveList();
Iterator<Subject> iterator2=electiveList.iterator();
while(iterator2.hasNext()){
logger.info("inside while :");
SubjectAllocatedToStudentBo bo=new SubjectAllocatedToStudentBo();
bo.setBacthId(dto.getBacthId());
bo.setSemester(dto.getSemester());
bo.setStudentId(dto.getStudentId());
Subject subject=iterator2.next();
bo.setSubjectName(subject.getSubjectName());
bo.setSubjectType(subject.getAbbreviation());
try{
manager.persist(bo);
}
catch(javax.persistence.PersistenceException e){
Throwable t = e.getCause();
while ((t != null) && !(t instanceof org.hibernate.exception.ConstraintViolationException)) {
t = t.getCause();
}//while
if (t instanceof org.hibernate.exception.ConstraintViolationException) {
throw new Exception("Elective subject already allocated to student");
} //end of if
}//end of catch
}//end of while
logger.info("allocateSubjectToStudent method exit :");
} //end of method
create three different method all with TranscationAttributeType REQUIRES_NEW
Please find below code snippet for EJB3 Bean
public void doYourWork()
{
a();
b();
c();
}
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void a()
{
try
{
//Do the first transaction here
}catch(Exception e)
{
}
}
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void b()
{
try
{
//Do the second transaction here
}catch(Exception e)
{
}
}
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void c()
{
try
{
//Do the third transaction here
}catch(Exception e)
{
}
}
Within a single method invocation there is only a single transaction active. To achieve what you want, you must perform the three operations in different transactions. This would require one more level of abstracttion.
public class MyFreshTransaction {
#TransactionAttribute(REQUIRES_NEW)
public void updateO() {
//do something
}
#TransactionAttribute(REQUIRES_NEW)
public void update1() {
//do something
}
#TransactionAttribute(REQUIRES_NEW)
public void update2() {
//do something
}
}
#Stateless
public class MyTransactionProcessor {
#EJB
private MyFreshTransaction freshTransaction;
public void processTransaction() {
try {
//The current transaction context will be suspended, and a new one invoked
//if the new one fails and is rollback, the current one is not affected.
//you can then handle the exception, by rethrowing the exception,in which case
//the current transaction will also be rolled back, or continue based on your logic.
freshTransaction.update0();
} catch (Exception ex ) {//handle}
try {
//The current transaction context will be suspended, and a new one invoked
//if the new one fails and is rollback, the current one is not affected.
//you can then handle the exception, by rethrowing the exception,in which case
//the current transaction will also be rolled back, or continue based on your logic.
freshTransaction.update1();
} catch (Exception ex ) {//handle}
try {
//The current transaction context will be suspended, and a new one invoked
//if the new one fails and is rollback, the current one is not affected.
//you can then handle the exception, by rethrowing the exception,in which case
//the current transaction will also be rolled back, or continue based on your logic.
freshTransaction.update2();
} catch (Exception ex ) {//handle}
}
}
Note that if any of the update transaction was successful, and the the parent transaction is rolled back, it will not affect the status of the 'child' transactions, as they had already been committed and their effects (if DB effects) will be committed too.
Read on Java EE Transactions Java EE Transactions

how to populate cvc-complex-type error information in mule

I have mule message filters to validate SOAP Request against schema,
my question is:
how to log error details of 'which element is have parse exception (cvc-complex-type). because catch block is always trowing exception details: "Message has been rejected by filter". how can i show exact exception?. so that user will enter correct data on request.
write a customfilterclass as a child of SchemaValidationfilter.
override accept method and throw soap fault.
public class CustomSchemaValidationFilter extends SchemaValidationFilter {
#Override
public boolean accept(MuleMessage muleMessage) {
return validateBody(muleMessage);
}
public boolean validateBody(MuleMessage message) throws Fault {
Source source = null;
try {
source = loadSource(message);
} catch (Exception e) {
throw getFaultObj(e);
}
try {
createValidator().validate(source);
} catch (SAXException e) {
throw getFaultObj(e);
} catch (IOException e) {
throw getFaultObj(e);
}
return true;
}
private Fault getFaultObj(Exception e) {
return new SoapFault(e.getMessage(), e, new QName(
DEFAULT_SCHEMA_LANGUAGE));
}
}
//and add in mule flow following tags to validate filter.
<custom-filter class="org.mule.module.xml.filters.CustomSchemaValidationFilter">
<spring:property name="schemaLocations" value="${approvalHistorySchemaLocation}" />
</custom-filter>**

Persisting an Entity after encountering Exception

If an Exception is thrown while persisting an entity X, in the catch block can a call be made to a different method to persist some entity Y?
#Transactional(propagation = Propagation.REQUIRED)
private X addNewX(X transientX) {
X x = null;
try {
x = xDao.makePersistent(transientX); // A DB constraint will be violated and Hibernate throws PersistenceException
} catch (RuntimeException e) {
createErrorRecord(transientX, e.getMessage());
}
return x;
}
Save extra information about the error:
#Transactional(propagation = Propagation.REQUIRED)
private void createErrorRecord(X x, String errMsg) {
try {
ImportError error = new ImportError(x.getBlah(), x.moreBlah(),
errMsg);
impErrDao.makePersistent(error);
} catch (RuntimeException re) {
logger.error(re.toString());
}
}
However, ImportError never gets persisted. I tried noRollbackFor for PersistenceException but to no avail.
Is there something that can be done here?
Thanks
Using AOP for logging such exceptions seems to be the right option.

Resources