Pages

Wednesday, June 15, 2011

EJB3 Method Invocation Timeouts

I have an application calling a remote method on a stateless session bean. This mehtod performs a whole heap of JPA transactions and thus can take quite some time to execute. The exact time is dependent on parameters passed in but mostly the call times out before the method can complete execution.

Something strange I noticed was that the JBoss TM doesn't actually stop the remote method, which continues execution (usually until completion) but only times out and aborts the method call. I would have thought the manager would want to interrupt any active thread that is running within a transaction that has timed out. But it seems you can control the two timeouts separately.

To control the EJB method timeout set the transaction timeout to a higher value. This can be done on a per method basis by annotating the method with

        @org.jboss.annotation.ejb.TransactionTimeout(600) // eg: a 10 minute timeout.

Or to apply the timeout setting to the entire bean:

        @ActivationConfigProperty(propertyName="transactionTimeout", propertyValue="600")

For bean managed transactions you can set the timeput pn the UserTransaction as follows:

        UserTransaction ut = (UserTransaction)ctx.lookup        ("java:someApp/someBean/SomeTransaction");
        ut.setTransactionTimeout(600);
        ut.begin();
        ...
        ut.commit();



To set the read timeout for remote method invocations in JBoss (6), update the following line in <JBoss home>/server/default/deploy/ejb3-connectors-jboss-beans.xml with:

        </parameter>
        <parameter>socket://${hostforurl}:${port}?timeout=600000</parameter>
        <parameter>

Monday, June 6, 2011

JPA-style positional param was not an integral ordinal

My JPA named native query:

 @NamedNativeQuery(
   name = "getFailure",
   query = "SELECT * " +
   "FROM INTERFACE_FAILURES " +
   "WHERE server_id = ?1" +
   "AND interface_name = ?2" +
   "AND date_time = TO_DATE(?3, 'dd/MM/yyyy hh:mi:ss PM') ",
   resultClass = InterfaceFailure.class
 )

called as follows:

   Query query = entityManager.createNamedQuery("getFailure")
   .setParameter(1, serverId)
   .setParameter(2, interfaceId)
   .setParameter(3, dateTime);

   if(query.getResultList().size() > 0) {
     failure = (InterfaceFailure)query.getSingleResult();   
   }


results in the following:

15:54:33,438 ERROR [org.hibernate.impl.SessionFactoryImpl] Error in named query: getFailure: org.hibernate.QueryException: JPA-style positional param was not an integral ordinal
 at org.hibernate.engine.query.ParameterParser.parse(ParameterParser.java:111) [:3.6.0.Final]
 at org.hibernate.loader.custom.sql.SQLQueryParser.substituteParams(SQLQueryParser.java:290) [:3.6.0.Final]
...


The solution, which google did not help with at all, hence my post:

 @NamedNativeQuery(
   name = "getFailure",
   query = "SELECT * " +
   "FROM INTERFACE_FAILURES " +
   "WHERE server_id = (?1)" +
   "AND interface_name = (?2)" +
   "AND date_time = TO_DATE(?3, 'dd/MM/yyyy hh:mi:ss PM') ",
   resultClass = InterfaceFailure.class
 )


Add brackets around the integral positional parameters. 

Issues with JPA Queries with Date constraints

Lately I have been trying to update an Oracle table with a primary key made up of a start date and end date using JPA merge. The merge step was throwing ConstraintViolationExceptions saying that the primary key already existed, which was strange because as far as I thought merge was only supposed to try and insert rows if an existing match didn't exist, in which case we should not ever see constraint violations of this sort.


Due to my still sketchy understanding of JPA I figured creating a new entity object could somehow be causing an automatic database synchronisation step, which results in the Constraint violation exception.

I decided to try searching for the existing record before creating it if the search result came back with null. I added the following query:

   @NamedNativeQuery(
   name = "getUserLogEntry",
   query = "SELECT * " +
   "FROM USER_LOG_ENTRY " +
   "WHERE start_date_time = ?1 " +
   "AND end_date_time = ?2 ",
   resultClass = UserLogEntry.class
   )

Which is called passing in Date objects as parameters:

   Query query = entityManager.createNamedQuery("getUserLogEntry")
   .setParameter(1, startDate, TemporalType.DATETIME)
   .setParameter(2, endDate, TemporalType.DATETIME);

   if(query.getResultList().size() > 0) {
     entry = (UserLogEntry)query.getSingleResult();   
   }

This however, was not finding any entry in the database, even though there definitely was such an entry there!

After much wasted time I did find a way aroung this (although not a full understanding of why the previous attempts were not working). It seems passing java Date objects to the SQL query somehow scrambles somewhere in the Date translation, resulting in no matches. Therefore I casted my java dates to Strings and then used SQL's TO_DATE to format the dates exactly as I wanted:

   @NamedNativeQuery(
   name = "getUserLogEntry",
   query = "SELECT * " +
   "FROM HC_DYN_USER_LOG_ENTRY " +
   "WHERE start_date_time = TO_DATE(?1, 'dd/MM/yyyy hh:mi:ss PM') " +
   "AND end_date_time = TO_DATE(?2, 'dd/MM/yyyy hh:mi:ss PM') ",
   resultClass = UserLogEntry.class
   )


    private static SimpleDateFormat reportDateFormat = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss a"); 

...


  String startDateStr = reportDateFormat.format(startDateTime);
  String endDateStr = reportDateFormat.format(endDateTime);
  Query query = entityManager.createNamedQuery("getUserLogEntry")
   .setParameter(1, startDateStr)
   .setParameter(2, endDateStr);
 
   if(query.getResultList().size() > 0) {
     entry = (UserLogEntry)query.getSingleResult();   
   }

JPA Queries

Recently started having to use JPA (at the whim of some senior) without having had any proper training on it. As expected I have run into a myraid of issues, one of them being referring to attributes of an embedded primary key class (ie: an entity generated from a table named <tableName>PK). Trying to refer to attributes of the embedded class using standard JPQL would result in errors such as “No data type for node org.hibernate.hql.ast.tree.AggregateNode”.

My temporary solution is to use named native queries instead, allowing me to write straight SQL. For example, in the entity class itself, you would have something like:


@Entity
@Table(name="LOG_ENTRY")
@NamedNativeQueries ({
 @NamedNativeQuery(
   name = "getLatestLogEntryDate",
   query = "SELECT * " +
   "FROM LOG_ENTRY e " +
   "WHERE e.start_date_time = (SELECT MAX(start_date_time) FROM LOG_ENTRY) ",
   resultClass = LogEntry.class
 )
})


public class LogEntry implements Serializable {
 private static final long serialVersionUID = 1L;

 @EmbeddedId
 private LogEntryPK id;

 @Column(name="AVG_TIME")
 private BigDecimal avgTime;

...

}


@Embeddable
public class LogEntryPK implements Serializable {
 //default serial version id, required for serializable classes.
 private static final long serialVersionUID = 1L;

 @Column(name="SERVER_ID")
 private String serverId;

    @Temporal( TemporalType.TIMESTAMP)
 @Column(name="START_DATE_TIME")
 private java.util.Date startDateTime;

    @Temporal( TemporalType.TIMESTAMP)
 @Column(name="END_DATE_TIME")
 private java.util.Date endDateTime;

...

}


This allows reference to startDateTime within the ServiceLogEntryPK class.


Another issue was developing queries that needed to return composite data, which is not itself an entity. For example, returning server_id, start_date_time, and the average of avg_time, grouped by month. This can be done by adding a named native query to the LogEntry class as follows:


@NamedNativeQueries ({
 @NamedNativeQuery(
   name = "getLogEntriesAggregateMonthly",
   query = "SELECT 'All Servers' as server_id, TO_CHAR(start_date_time, 'YYYY-MM') DATE_FIELD, AVG(e.AVG_TIME) as AVG_TIME " + 
   "FROM LOG_ENTRY e " +  
   "WHERE start_date_time >= TO_DATE(?1, 'yy.MM.dd') " + 
   "AND end_date_time <= TO_DATE(?2, 'yy.MM.dd') " +
   "AND server_id like (?3) " +
   "GROUP BY TO_CHAR(start_date_time, 'YYYY-MM')",
         resultSetMapping = "LogSummary"
 )
})
@SqlResultSetMappings({
 @SqlResultSetMapping(name="LogSummary")
})


The SqlResultSetMapping name is just a String token, and can be pretty much any randomly chosen string. (Don't ask me what the purpose of this is)

A good discussion on the weaknesses of JPA queroes can be found here: http://heapspace.blogspot.com/2009/03/jpa-strengths-and-weaknesses.html

Sunday, March 20, 2011

Viewing tables in Hypersonic

To view tables in the Hypersonic database that comes with JBoss, ensure JBoss is started and go to the JMX Management Console at http://localhost:<port>/jmx-console. <port> is usually 8080. In the Management Console under the JBoss heading click on the link called service=Hypersonic to go to the MBean view. Here you will see a list of MBean operations. Click on the invoke button for startDatabaseManager() to start up the HSQL Database manager. You should then see your database table in the tree to the left and an area where you can execute SQL statements.

Friday, February 11, 2011

Overview of popular software design patterns

Singleton
Ensure that only one instance of a class is created. To implement this, make the constructor protected (unit tests may need to access it), have a private static member which is an instance of itself, and have a get method that instantiates the class only if one does not already exist. 

Use of singletons can be abused. They are a little like global variables. Systems relying on global state hide their dependencies. Some arguments against using it: 
  • It promotes tight coupling between classes 
  • It violates the single responsibility principle - a class should not case whether it is a singleton.
They can be fairly safely used when they don't contain any mutable state. An example of an appropriate use of a singleton may be a global resource manager.

Factory
Creates objects without exposing the instantiation logic to the client and refers to the newly created object through a common interface. A simple implementation would be to have an interface and some implementing classes. The factory will return an instance of the superclass. Which subclass it is will depend on parameters passed in to the creation/get method.

Factory Method
Defines an interface for creating objects, but lets subclasses decide which class to instantiate and refers to the newly created object through a common interface.

MVC
Separates the model, view, and controller, or presentation, logic, and data.

DAO
Abstracts and encapsulates all access to the data source. The DAO manages the connection with the data source to obtain and store data.

Facade
Provides a unified, convenient interface to a set of existing interfaces, potentially hiding some components/interfaces. It provides flexibility to change/replace "hidden" subsystems including interfaces.

Prototype
Specifies the kinds of objects to create using a prototypical instance, and creates new objects by copying this prototype.

Strategy
Defines a family of algorithms, encapsulating each one and making them interchangeable. The strategy pattern lets the algorithm vary independently from clients that use it.

Observer
Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Command
Encapsulates a request in an object allowing the parameterisation of clients with different requests and allows saving the requests in a queue.

Visitor
Represents an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

Decorator
Adds additional responsibilities dynamically to an object.

Flyweight
Uses sharing to support a large number of objects that have part of their internal state in common where the other part of their state can vary.

Proxy
Provides a placeholder for an object to control references to it.

Bridge
Increases flexibility by letting abstraction and implementation evolve independently. This is achieved by having separate layers for abstraction and implementation, with a fixed implementation interface.



Thursday, February 10, 2011

J2EE Overview

Yes, there are so many other sites out there that provide J2EE Overviews but this is probably the most breif but yet complete one you'll find.

J2EE defines standards for developing multitier enterprise applications. It simplifies enterprise applications by basing them on standardised, modular components, and providing a set of services to those components. It handles many details of application behaviour automatically, without requiring complex programming.

Enterprise JavaBeans
EJB is a standard distributed object framework and component model. It defines several types of components: session beans, entity beans, message driven beans, which simplify application development by concealing application complexity and enabling the component designer to focus on business logic.

Servlets and JSPs
Servlets and Java Server Pages are complementary APIs, both providing a means for generating dynamic web content. Servlets are Java programs implementing the javax.servlet.Servlet interface and running in a Web/App server's servlet engine. JSPs contain a mixture of HTML and java scripts, JSP elements, and directives, and are compiled into Servlets by the JSP engine.

JDBC
JDBC is a set of interfaces allowing Java applications to access any database.

RMI
RMI is an API which allows Java objects to communicate remotely with other objects. Its equivalent from OMG is CORBA.

IDL
IDL is a standard platform-independent language used to define interfaces that object implemnetation provide and client objects call. It allows java objects to communicate with other objects in any language.

JMS
JMS API is a messaging standard that allows J2EE components to create, send, receive, and read messages. It enables distributed communication between components. The addition of the JMS API enhances the J2EE platform by simplifying enterprise development, allowing loosely coupled, reliable, asynchronous interactions among J2EE components and legacy systems capable of messaging.

JTA
JTA allows J2EE components to perform distributed transactions.

JavaMail
JavaMail API allows Java components to send and receive emails.

JAXP (includes JAXB which is sometimes mentioned separately?)
Java API for XML Processing allows java applications to parse and transform XML documents.

JNDI
Java Naming and Directory Interface is a protocol which provides a standard API to access naming and directory services. It allows Java applications to find any necessary resource in a standard way.


Why use J2EE?
  • It is a standardised and reliable software architecture
  • that gives a lot of flexibility
  • is well documented,
  • with low level services already implemented.

Should foreign keys always be indexed?

In my opinion, mostly yes. The query optimizer will make a decision on whether it will be faster to use it or not. Indexes may not be of much use for low cardinality reference columns and will not be used by the optimiser.

On a Star Schema there may be some benefit from indexing low cardinality columns. This will give the query optimiser the option of using index intersection.

Foreign key indexing may not be desirable for purely data warehousing tables that are frequently batch loaded. The index write traffic will be large if there are many indexed columns and it may be necessary to disable foreign keys and indexes for these kinds of operations.

A more obscure reason for ensuring foreign keys are always indexed is the following - A delete from the parent table may lock the child table, which may result in a deadlock.

Unexpected behaviour with JUnit ExpectedException

The JUnit ExpectedException allows specification of expected exception types and messages. One would think that code throwing the exception would carry on executing any lines following it as the exception is expected. This is not the case.

The solution is to make sure that the code throwing the exception is the last line of the method.
 
Powered by Blogger