Wednesday, November 16, 2011

Using Exception Handlers in CXF

I was developing a web application and used Apache CXF for developing RESTful web-services. During the development we often come across scenarios where the expected entity does not exist in database. In RESTful web-services we form our own URLs to access the web-service and get the response. It is a common test scenario where one can try to access some data using such urls and that data may not be present in database at all.
For Example, lets see I am accessing company information using its name via webservice.

Say the URL looks like http://localhost:8080/resource/company/developmentCompany.


Lets say but the database does not contain any row for developmentCompany. Obviously the query will fail and end up throwing exception.


We can always handle such exceptions using null checks but it is more accurate to handle such exceptions using some ExceptionMappers which will show some User friendly message. In CXF, we can create our own ExceptionMappers to handle such scenarios in following way.


    Create your own Mapper class which will implement
     javax.ws.rs.ext.ExceptionMapper interface and use the actual exception  
    class as a parameter class to javax.ws.rs.ext.ExceptionMapper. Now your 
    mapper class needs to implement the method toResponse(E exception).

public class NoResultMapper implements ExceptionMapper<javax.persistence.noresultexception>{
  private static Logger logger = Logger.getLogger(NoResultMapper.class.getName());
  @Override
  public Response toResponse(NoResultException exception) {
  logger.warn("Result not found.. The entity does not exist in database." + exception.getCause() + ": " +                   
                                 exception.getMessage());
  return Response.serverError().entity(new GenericError("Result not found.. The entity does not exist in database.",   
  exception.getCause() + ": " + exception.getMessage())).build();
}

After creating your own mapper, you need to declare your mapper in your service beans xml file.

<bean id="noResultMapper" class="exceptionMappers.NoResultMapper" /> 

Tuesday, November 15, 2011

Enables/Disable CXF Logging (payload)

I was using Apache CXF web-service framework. Its usually good to have logging enabled in applications. But with cxf I observed that cxf keeps logging the payload of every response received from a web-service. The web service was returning images which massively affected the size of log files. I used log4j logger to log the messages and removed the cxf logging.


To remove cxf logging just comment out or remove code the following code from your cxf configuration xml file.
   
          
                            
  
        
            
        
  

Sunday, November 6, 2011

EclipseLink: Null primary key encountered in unit of work clone

I came across this weird issue while using EclipseLink 2.0 with JPA 2.0. It isn't actually that complicated as it looks. Though I spent lot of time figuring out whether any objects have null id or negative id. Finally figured out that, The database had rows with id as '0'. By default EclipseLink treats zero ids as null. I don't


Simple fix is to tell EclipseLink to treat '0' as a valid id and not null. It can be done by specifying the property in persistence.xml 


In persistence.xml add the following property to get rid of this exception. 


     <property name="eclipselink.allow-zero-id" value="true"/>


This property simply tells EclipseLink to treat '0' as a valid primary key instead of null.