Show SQL queries while JPA CriteriaQuery execution

In persistence.xml add following properties:

	<property name = "hibernate.show_sql" value = "true" />
	<property name = "hibernate.format_sql" value = "true" />
	<property name = "hibernate.use_sql_comments" value = "true" />

I am using JBOSS EAP for deployment, so in standalone xml, I need to add new logger categories as:

	<logger category="org.hibernate.type">
		<level name="TRACE"/>
	</logger>
	<logger category="org.hibernate.SQL">
		<level name="TRACE"/>
	</logger>

That’s all!

Few notes on MDBs

1) The MDB must be defined as public and cannot be declared as final or abstract. In addition, it
needs a public default constructor and cannot have a finalize method.

2) The PreDestroy method may not be invoked if the EJB container crashes or a
system exception is thrown by the MDB.

3) Different types of messages:
TextMessage – A Java String object
BytesMessage – An unformatted stream of bytes
StreamMessage – A stream of bytes based on primitive Java data types
MapMessage – A set of key/value pairs
ObjectMessage – Contains a Java object

4) @ActivationConfigProperty: It is an array of activation config properties for this MDB.

Property Description
String destination The JNDI name of the Queue or Topic – MANDATORY
String destinationType The type of destination – valid values are javax.jms.Queue or javax.jms.Topic
String messageSelector The message selector of the subscription
int acknowledgeMode The type of acknowledgement when using non-transacted JMS – valid values are, AUTO_ACKNOWLEDGE ,
DUPS_OK_ACKNOWLEDGE. Default is AUTO_ACKNOWLEDGE
String clientID the client id of the connection
boolean subscriptionDurability Whether topic subscriptions are durable – valid values Durable or NonDurable.
Default is NonDurable
String subscriptionName the subscription name of the topic subscription

5) subscriptionDurability:
When using MDB topic, we can specify whether the topic subscription is durable or not.

– Non durable subscription:
A subscriber will not receive a copy of a message when he is not connected to a topic when a message arrived at the destination.
This is the default property value.

– Durable subscription
If a durable subscriber is not connected to a topic when a message is received, MOM retains a copy of the message until the subscriber connects and delivers the message.

6) messageSelector
A message selector allows a JMS consumer to be more selective about the messages that it receives from a particular topic or queue. A message selector uses message properties and headers as criteria in conditional expressions. These expressions use Boolean logic to declare which messages should be delivered to a client. e.g.

@ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "OrderAmount > 10000")

Concurrency management in EJBs

Concurrency management in EJBs

1) Stateless beans:
No explicit concurrency management can be configured for stateless beans. Same Stateless EJB may never be concurrently accessed by more than a single client call. Every client request uses new instance from pool.
If pool becomes exhausted when a client request arrives (ex: the pool has reached its maximum size) an exception will be thrown and propagated to the remote client.

2) Stateful beans:
For business methods in stateful beans, lock type is always set to WRITE (container managed concurrency). So only single client request thread can access only single methods of stateful bean. Other client requests will wait till the execution of previous thread is complete.
The lock type cannot be changed (its always WRITE). Only the access-timeout value can be modified for stateful session beans.

@AccessTimeout(value = 4000)
@AccessTimeout(value = 2, unit = TimeUnit.SECONDS)

Default access timeout is set to 5000 ms. In case of JBOSS server, it is configured using EJB subsystem:

<subsystem xmlns="urn:jboss:domain:ejb3:1.4">
	<session-bean>
		<stateless>
			<bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
		</stateless>
		<stateful default-access-timeout="5000" cache-ref="simple"/>
		<singleton default-access-timeout="5000"/>
	</session-bean>
	...
	...

Stateful session beans cannot be configured to use bean-managed concurrency.

3) Singleton beans:
By default, every Singleton EJB has WRITE lock type for all methods (@Lock(LockType.WRITE)). LockType.READ is applicable only in case of singleton beans.

Also bean managed concurrency is applicable only to singleton beans.

@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class SingletonEJB {
  public void someMethod() {

  }
}

@Lock and @AccessTimeout are ignored when you use, ConcurrencyManagementType.BEAN. In this case access is restricted using synchronized keyword.

Configuring embedded Derby as a datasource in JBOSS EAP 6.x

1) In eclipse, in data source explorer view, create new database connection. Select Derby as connection profile type. Give any name for your database.

derby1
Then select correct connection driver details, give username and password and then click on finish. Before clicking on finish, note down database URL.

derby2

2) Download latest derby.jar for embedded database. copy it inside your JBOSS modules directory at path:

{JBOSS_HOME}\modules\org\apache\derby\main

If path is not present, create it. Then create module.xml file in same path and put following contents into it:

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="org.apache.derby">
	<resources>
		<resource-root path="derby.jar"/>
	</resources>
	<dependencies>
		<module name="javax.api"/>
		<module name="javax.transaction.api"/>
		<module name="javax.servlet.api" optional="true"/>
	</dependencies>
</module>

You can download derby.jar from maven repo.

3) In standalone.xml, configure datasource subsystem:

<subsystem xmlns="urn:jboss:domain:datasources:1.1">
	<datasources>
		<datasource jndi-name="java:/DerbyDS" pool-name="DerbyDS" enabled="true" use-ccm="false">
			<connection-url>jdbc:derby:C:\temp\DevDB</connection-url>
			<driver>org.apache.derby</driver>
			<security>
				<user-name>admin</user-name>
				<password>admin</password>
			</security>
			<validation>
				<validate-on-match>false</validate-on-match>
				<background-validation>false</background-validation>
			</validation>
			<statement>
				<share-prepared-statements>false</share-prepared-statements>
			</statement>
		</datasource>
		<drivers>
			<driver name="org.apache.derby" module="org.apache.derby">
				<xa-datasource-class>org.apache.derby.jdbc.EmbeddedXADataSource</xa-datasource-class>
			</driver>
		</drivers>
	</datasources>
</subsystem>

Database URL noted down in step 1, is put in-between tags. Use user-name and password configured in step 1 above. Note down jndi name which you have configured here (java:/DerbyDS).

4) Use jndi name configured in step above, inside your persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
	<persistence-unit name="jpa" transaction-type="JTA">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>
		<jta-data-source>java:/DerbyDS</jta-data-source>
		<class>entities.Parts</class>
		<properties>
		  <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" />
	      <property name="hibernate.default_schema" value="APP"/>
	       <property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.EmbeddedDriver"/>
      	</properties>
	</persistence-unit>
</persistence>

Note down persistence unit name configured over here, you need to use it while injecting datasource in your java code.

5) Now you can inject your datasource inside your java code using:

@PersistenceContext(unitName = "jpa")
private EntityManager em;

Note: You can start only single instance of embedded Derby database. So before you deploy your application on server, disconnect DB instance configured in eclipse. Otherwise you may get similar to connection already open.

Simple JMS application based on JBOSS EAP 6.x

1) Add new messaging extension in standalone.xml:

	</extensions>
	...
	...
	<extension module="org.jboss.as.messaging"/>
	</extensions>

2) Configure messaging domain in standalone.xml. Configure hornetq server.:

	<subsystem xmlns="urn:jboss:domain:messaging:1.3">
		<hornetq-server>
			<persistence-enabled>true</persistence-enabled>
			<journal-file-size>102400</journal-file-size>
			<journal-min-files>2</journal-min-files>

			<connectors>
				<netty-connector name="netty" socket-binding="messaging"/>
				<netty-connector name="netty-throughput" socket-binding="messaging-throughput">
					<param key="batch-delay" value="50"/>
				</netty-connector>
				<in-vm-connector name="in-vm" server-id="0"/>
			</connectors>

			<acceptors>
				<netty-acceptor name="netty" socket-binding="messaging"/>
				<netty-acceptor name="netty-throughput" socket-binding="messaging-throughput">
					<param key="batch-delay" value="50"/>
					<param key="direct-deliver" value="false"/>
				</netty-acceptor>
				<in-vm-acceptor name="in-vm" server-id="0"/>
			</acceptors>

			<security-settings>
				<security-setting match="#">
					<permission type="send" roles="guest"/>
					<permission type="consume" roles="guest"/>
					<permission type="createNonDurableQueue" roles="guest"/>
					<permission type="deleteNonDurableQueue" roles="guest"/>
				</security-setting>
			</security-settings>

			<address-settings>
				<address-setting match="#">
					<dead-letter-address>jms.queue.DLQ</dead-letter-address>
					<expiry-address>jms.queue.ExpiryQueue</expiry-address>
					<redelivery-delay>0</redelivery-delay>
					<max-size-bytes>10485760</max-size-bytes>
					<address-full-policy>BLOCK</address-full-policy>
					<message-counter-history-day-limit>10</message-counter-history-day-limit>
				</address-setting>
			</address-settings>

			<jms-connection-factories>
				<connection-factory name="InVmConnectionFactory">
					<connectors>
						<connector-ref connector-name="in-vm"/>
					</connectors>
					<entries>
						<entry name="java:/ConnectionFactory"/>
					</entries>
				</connection-factory>
				<connection-factory name="RemoteConnectionFactory">
					<connectors>
						<connector-ref connector-name="netty"/>
					</connectors>
					<entries>
						<entry name="RemoteConnectionFactory"/>
						<entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
					</entries>
				</connection-factory>
				<pooled-connection-factory name="hornetq-ra">
					<transaction mode="xa"/>
					<connectors>
						<connector-ref connector-name="in-vm"/>
					</connectors>
					<entries>
						<entry name="java:/JmsXA"/>
					</entries>
				</pooled-connection-factory>
			</jms-connection-factories>

			<jms-destinations>
				<jms-queue name="testQueue">
					<entry name="queue/MyQueue"/>
				</jms-queue>
				<jms-topic name="testTopic">
					<entry name="topic/MyTopic"/>
				</jms-topic>
			</jms-destinations>
		</hornetq-server>
	</subsystem>

3) Create new MDB:

@MessageDriven(activationConfig = {
		@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
		@ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/MyQueue"),
		@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })
public class MessageBean implements MessageListener {

4) Override onMessage() method:

	public void onMessage(Message message) {
		if (message instanceof TextMessage) {
		...
		...
		}
	}

5) Sample test client:

@WebServlet("/TextServlet")
public class TextServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Resource(mappedName = "java:/ConnectionFactory")
	private QueueConnectionFactory queueConnectionFactory;

	@Resource(mappedName = "java:/queue/MyQueue")
	private Queue queue;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response);
	}

	protected void processRequest(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		try {
			Connection connection = null;
			try {
				connection = queueConnectionFactory.createConnection();
				Session session = connection.createSession(false,
						Session.AUTO_ACKNOWLEDGE);
				MessageProducer messageProducer = (MessageProducer) session
						.createProducer(queue);
				TextMessage textMessage = session.createTextMessage();
				String message = "test";
				textMessage.setText(message);
				messageProducer.send(textMessage);
				System.out.println("---> Text Message Sent");
			} catch (JMSException ex) {
				Logger.getLogger(TextServlet.class.getName()).log(Level.SEVERE,
						null, ex);
			} finally {
				if (connection != null) {
					try {
						connection.close();
					} catch (JMSException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			out.println("<html>");
			out.println("<head>");
			out.println("<title>Servlet TextServlet</title>");
			out.println("</head>");
			out.println("<body>");
			out.println("<h1>Servlet TextServlet at "
					+ request.getContextPath() + "</h1>");
			out.println("</body>");
			out.println("</html>");
		} finally {
			out.close();
		}
	}
}

6) In case of Topic:

@MessageDriven(activationConfig = {
		@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
		@ActivationConfigProperty(propertyName = "destination", propertyValue = "topic/MyTopic"),
		@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
		@ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "Durable"),
		@ActivationConfigProperty(propertyName = "clientId", propertyValue = "SubscriberBean"),
		@ActivationConfigProperty(propertyName = "subscriptionName", propertyValue = "SubscriberBean"),
		@ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "test = 'tested' AND number < 10")})
public class SubscriberBean implements MessageListener {

And client looks like:

	@Resource(mappedName = "java:/ConnectionFactory")
	private TopicConnectionFactory topicConnectionFactory;

	@Resource(mappedName = "java:/topic/MyTopic")
	private Topic topic;

	Connection connection = topicConnectionFactory.createConnection();
	Session session = connection.createSession(false,
			Session.AUTO_ACKNOWLEDGE);
	MessageProducer messageProducer = (MessageProducer) session
			.createProducer(topic);
	ObjectMessage availabilityMessage = session
			.createObjectMessage();
	availabilityMessage.setStringProperty("test", "tested");
	availabilityMessage.setIntProperty("number", 10);
	messageProducer.send(availabilityMessage);