More interesting articles
Next portion of interesting articles from dZone
Understanding JVM internals
How to analyze Java thread dumps
Practicing Code, Java, and Databases
10 Things I Never Want to See a Java Developer Do Again
jQuery Kwicks - Sexy Sliding Panels And Navigational Interaction
Why Do Bad Things Happen to Good Code?
and sth about Apache Camel
Understanding JVM internals
How to analyze Java thread dumps
Practicing Code, Java, and Databases
10 Things I Never Want to See a Java Developer Do Again
jQuery Kwicks - Sexy Sliding Panels And Navigational Interaction
Why Do Bad Things Happen to Good Code?
and sth about Apache Camel
Hibernate inheritance table per subclass with different foreign key names
In one of the projects we were supposed to implement an inheritance in the db. The project based on Spring and Hibernate so we could pick one of the three inheritance methods. We decided to pick the inheritance of table for subclass. The problem as been discussed in many ways but it is not common that the names of the foreign keys are not equal to the name of the primary key.
This is a diagram of a database that will be used in our example. As far as logic goes - we have an abstraction called ABSENCE that can be either a recursive absence (REC_ABSENCE) or a month recursive absence (MONTH_REC_ABSENCE).
The recursive absence and the month recursive absence are differing from the absence in terms of data being held more than in terms of the behavior.
Of course from the logical point of view, this example can have little sense but it is just an example so don't focus on the business side.
Absence.java
package pl.grzejszczak.marcin.entity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;
/**
* Absence generated by hbm2java
*/
@Entity
@Table(name = "ABSENCE")
@Inheritance(strategy = InheritanceType.JOINED)
public class Absence implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = -4572952141587410338L;
private int id;
private int version;
private Date startDate;
private Date endDate;
public Absence() {
}
@Id
@Column(name = "ID", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
@Version
@Column(name = "VERSION", nullable = false)
public int getVersion() {
return this.version;
}
public void setVersion(int version) {
this.version = version;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "START_DATE", nullable = false, length = 23)
public Date getStartDate() {
return this.startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "END_DATE", length = 23)
public Date getEndDate() {
return this.endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
}
RecursiveAbsence.java
Note that you do not have to explicitly create an id field. You define it by means of an annotation @PrimaryKeyJoinColumn with providing the name of the id column for the given entity (REC_ABSENCE_ID) and the name of the column for the id it is referencing (ID in the ABSENCE table).
package pl.grzejszczak.marcin.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
/**
*
* Hibernate mapping strategy: Inheritance mapping: joined subclasses (table per
* subclass)
*
*/
@Entity
@Table(name = "REC_ABSENCE")
@PrimaryKeyJoinColumn(name = "REC_ABSENCE_ID", referencedColumnName = "ID")
public class RecursiveAbsence extends Absence implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private boolean isMonthly;
private boolean isWeekly;
public RecursiveAbsence() {
}
@Column(name = "isMONTHLY", nullable = false, precision = 1, scale = 0)
public boolean getIsMonthly() {
return this.isMonthly;
}
public void setIsMonthly(boolean isMonthly) {
this.isMonthly = isMonthly;
}
@Column(name = "isWEEKLY", nullable = false, precision = 1, scale = 0)
public boolean getIsWeekly() {
return this.isWeekly;
}
public void setIsWeekly(boolean isWeekly) {
this.isWeekly = isWeekly;
}
}
MonthRecursiveAbsence.java
Issue with the referencing of the column name as in the previous example.
package pl.grzejszczak.marcin.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Transient;
@Entity
@Table(name = "MONTH_REC_ABSENCE")
@PrimaryKeyJoinColumn(name = "MONTH_ABSENCE_ID", referencedColumnName = "ID")
public class MonthRecursiveAbsence extends Absence implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 7844275381822579686L;
private Integer monthId;
public MonthRecursiveAbsence() {
}
@Transient
public MonthDefinitionEnum getMonth() {
return MonthDefinitionEnum.getByKey(monthId);
}
@Column(name = "MONTH_ID")
public Integer getMonthId() {
return monthId;
}
public void setMonthId(Integer monthId) {
this.monthId = monthId;
}
}
Spring BeanPostProcessor for a specified type
I was recently having a discussion how can one use a BeanPostProcessor to execute some logic for a specified class.
Looking at the Javadoc for the BeanPostProcessor one can read that:
Factory hook that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies.So how can one create in an easy way a BeanPostProcessor for a precise type without creating a cascade of ifs or instance ofs? This is my concept of solving this problem - perhaps you know an easier one? :)
SomeService.java
package pl.grzejszczak.marcin.postprocessor;
public interface SomeService {
void methodA();
void methodB();
}
SomeServiceImpl.java
package pl.grzejszczak.marcin.postprocessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SomeServiceImpl implements SomeService {
private static final Logger LOGGER = LoggerFactory.getLogger(SomeServiceImpl.class);
public SomeServiceImpl() {
LOGGER.debug("SomeServiceImpl - I'm created!");
}
private void afterInit() {
LOGGER.debug("SomeServiceImpl - After init!");
}
private void destroyMethod() {
LOGGER.debug("SomeServiceImpl - Destroy Method!");
}
@Override
public void methodA() {
LOGGER.debug("SomeServiceImpl - Method A executed");
}
@Override
public void methodB() {
LOGGER.debug("SomeServiceImpl - Method B executed");
}
}
SomeOtherService.java
package pl.grzejszczak.marcin.postprocessor;
public interface SomeOtherService {
void methodC();
void methodD();
}
SomeOtherServiceImpl.java
package pl.grzejszczak.marcin.postprocessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SomeOtherServiceImpl implements SomeOtherService {
private static final Logger LOGGER = LoggerFactory.getLogger(SomeOtherServiceImpl.class);
public SomeOtherServiceImpl() {
LOGGER.debug("SomeOtherServiceImpl - I'm created!");
}
private void afterInit() {
LOGGER.debug("SomeOtherServiceImpl - After init!");
}
private void destroyMethod() {
LOGGER.debug("SomeOtherServiceImpl - Destroy Method!");
}
@Override
public void methodC() {
LOGGER.debug("SomeOtherServiceImpl - Method C executed");
}
@Override
public void methodD() {
LOGGER.debug("SomeOtherServiceImpl - Method D executed");
}
}
AbstractBeanPostProcessor.java
package pl.grzejszczak.marcin.postprocessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public abstract class AbstractBeanPostProcessor<T> implements BeanPostProcessor {
private Class<T> clazz;
public AbstractBeanPostProcessor(Class<T> clazz) {
this.clazz = clazz;
}
@Override
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
checkConditions();
if (clazz.isAssignableFrom(bean.getClass())) {
doAfter();
}
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
checkConditions();
if (clazz.isAssignableFrom(bean.getClass())) {
doBefore();
}
return bean;
}
private void checkConditions() {
if (clazz == null) {
throw new NullArgumentException("Provide the interface for the post processor");
}
}
public abstract void doBefore();
public abstract void doAfter();
}
SomeServicePostProcessor.java
package pl.grzejszczak.marcin.postprocessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class SomeServicePostProcessor extends AbstractBeanPostProcessor<SomeService> {
private static final Logger LOGGER = LoggerFactory.getLogger(SomeServicePostProcessor.class);
public SomeServicePostProcessor() {
super(SomeService.class);
}
@Override
public void doBefore() {
LOGGER.info("BEFORE it's init method has been executed but AFTER SomeServiceImpl has been instantiated I would like to do sth...");
}
@Override
public void doAfter() {
LOGGER.info("AFTER SomeServiceImpl has executed its init method I would like to do sth more...");
}
}
SpringMain.java
package pl.grzejszczak.marcin.postprocessor;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringMain {
public static void main(String[] args) {
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
SomeService someService = context.getBean(SomeService.class);
someService.methodA();
someService.methodB();
SomeOtherService someOtherService = context.getBean(SomeOtherService.class);
someOtherService.methodC();
someOtherService.methodD();
context.close();
}
}
ApplicationContext.xml
<bean class="pl.grzejszczak.marcin.postprocessor.SomeServiceImpl" destroy-method="destroyMethod" init-method="afterInit"/>
<bean class="pl.grzejszczak.marcin.postprocessor.SomeOtherServiceImpl" destroy-method="destroyMethod" init-method="afterInit"/>
<bean class="pl.grzejszczak.marcin.postprocessor.SomeServicePostProcessor"/>
Logs
2012-10-23 00:20:38,863 INFO [main] org.springframework.context.support.ClassPathXmlApplicationContext:495 Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@28d11816: startup date [Tue Oct 23 00:20:38 CEST 2012]; root of context hierarchyAs you can see it is quite easy, using generics and the BeanPostProcessor, to specify certain behavors for a given type (generics and constructor of SomeServiceImpl) or a group of types of classes (generics and constructor of SomeService).
2012-10-23 00:20:38,956 INFO [main] org.springframework.beans.factory.xml.XmlBeanDefinitionReader:315 Loading XML bean definitions from class path resource [applicationContext.xml]
2012-10-23 00:20:39,213 INFO [main] org.springframework.beans.factory.support.DefaultListableBeanFactory:557 Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6bb4469: defining beans [pl.grzejszczak.marcin.postprocessor.SomeServiceImpl#0,pl.grzejszczak.marcin.postprocessor.SomeOtherServiceImpl#0,pl.grzejszczak.marcin.postprocessor.SomeServicePostProcessor#0]; root of factory hierarchy
2012-10-23 00:20:39,214 DEBUG [main] pl.grzejszczak.marcin.postprocessor.SomeServiceImpl:10 SomeServiceImpl - I'm created!
2012-10-23 00:20:39,215 INFO [main] pl.grzejszczak.marcin.postprocessor.SomeServicePostProcessor:18 BEFORE its init method has been executed but AFTER SomeServiceImpl has been instantiated I would like to do sth...
2012-10-23 00:20:39,216 DEBUG [main] pl.grzejszczak.marcin.postprocessor.SomeServiceImpl:14 SomeServiceImpl - After init!
2012-10-23 00:20:39,216 INFO [main] pl.grzejszczak.marcin.postprocessor.SomeServicePostProcessor:23 AFTER SomeServiceImpl has executed its init method I would like to do sth more...
2012-10-23 00:20:39,220 DEBUG [main] pl.grzejszczak.marcin.postprocessor.SomeOtherServiceImpl:10 SomeOtherServiceImpl - I'm created!
2012-10-23 00:20:39,221 DEBUG [main] pl.grzejszczak.marcin.postprocessor.SomeOtherServiceImpl:14 SomeOtherServiceImpl - After init!
2012-10-23 00:20:39,225 DEBUG [main] pl.grzejszczak.marcin.postprocessor.SomeServiceImpl:23 SomeServiceImpl - Method A executed
2012-10-23 00:20:39,241 DEBUG [main] pl.grzejszczak.marcin.postprocessor.SomeServiceImpl:28 SomeServiceImpl - Method B executed
2012-10-23 00:20:39,242 DEBUG [main] pl.grzejszczak.marcin.postprocessor.SomeOtherServiceImpl:23 SomeOtherServiceImpl - Method C executed
2012-10-23 00:20:39,242 DEBUG [main] pl.grzejszczak.marcin.postprocessor.SomeOtherServiceImpl:28 SomeOtherServiceImpl - Method D executed
2012-10-23 00:20:39,242 INFO [main] org.springframework.context.support.ClassPathXmlApplicationContext:1020 Closing org.springframework.context.support.ClassPathXmlApplicationContext@28d11816: startup date [Tue Oct 23 00:20:38 CEST 2012]; root of context hierarchy
2012-10-23 00:20:39,243 INFO [main] org.springframework.beans.factory.support.DefaultListableBeanFactory:433 Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6bb4469: defining beans [pl.grzejszczak.marcin.postprocessor.SomeServiceImpl#0,pl.grzejszczak.marcin.postprocessor.SomeOtherServiceImpl#0,pl.grzejszczak.marcin.postprocessor.SomeServicePostProcessor#0]; root of factory hierarchy
2012-10-23 00:20:39,244 DEBUG [main] pl.grzejszczak.marcin.postprocessor.SomeOtherServiceImpl:18 SomeOtherServiceImpl - Destroy Method!
2012-10-23 00:20:39,245 DEBUG [main] pl.grzejszczak.marcin.postprocessor.SomeServiceImpl:18 SomeServiceImpl - Destroy Method!
Interesting articles
Since one of my aims of starting a blog was to treat it as a notepad or a storage place for some interesting concepts regarding programming I recommend reading these articles:
How to tune Java Garbage Collector
NoSQL week review
Javascript and jQuery
Calculating Coherence cluster size on a remote server using JMX
In one of the projects I had a problem regarding calculating the size of a Oracle Coherence cluster. It doesn't seem to difficult since there is already a nice piece of code that can do it for us:
Calculating Coherence cluster size
The problem is that this code is working properly only if the Coherence cluster is not remote. So how can we access it?
We have to modify the following function
public static MBeanServer getMBeanServer() {
MBeanServer server = null;
for (Object o : MBeanServerFactory.findMBeanServer(null)) {
server = (MBeanServer) o;
if (DOMAIN_DEFAULT.length() == 0 ||
server.getDefaultDomain().equals(DOMAIN_DEFAULT)) {
break;
}
server = null;
}
if (server == null) {
server = MBeanServerFactory.createMBeanServer(DOMAIN_DEFAULT);
}
return server;
}
To this one
public static MBeanServerConnection getMBeanServer() throws IOException {
JMXServiceURL url = new JMXServiceURL("service://...");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
return jmxc.getMBeanServerConnection();
}
And modify the line
MBeanServer server = getMBeanServer();
To use the new interface
MBeanServerConnection server = getMBeanServer();
More information on how to define the Coherence JMX service URL and JMX for Coherence as such can be found here
Managing Coherence using JMX
Simulation of time consuming actions in integration tests
Hi!
Quite recently in one of my projects I had a situation in which I needed to create an integration test for the application. That's not very odd isn't it? :)
What was interesting was the fact that the logic of the app involved some concurrency issues and one of the components had to connect to an external service which would take a couple of seconds. Since in the integration test there was no need to make the actual connection, the component needed to be mocked. What about the simulation of the time consuming action? Well, let's take a look at the way I did it...
The task.
package pl.grzejszczak.marcin;The integration test.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Service that does some things including processing of the external service
*
* @author marcin
*
*/
public class SomeTask implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(SomeTask.class);
// Service is injected via a dependency injection system
private Processable timeConsumingExternalService;
private void methodThatConnectsToExternalServices() {
// connects to an external service and spends a couple of seconds there
LOGGER.debug("Before processing");
timeConsumingExternalService.process();
LOGGER.debug("After processing");
// some other things to do
}
public void run() {
methodThatConnectsToExternalServices();
}
public void setTimeConsumingExternalService(Processable timeConsumingExternalService) {
this.timeConsumingExternalService = timeConsumingExternalService;
}
}
package pl.grzejszczak.marcin;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ServiceIntegrationTest {
private static final Logger LOGGER = LoggerFactory.getLogger(ServiceIntegrationTest.class);
private ExecutorService executorService = Executors.newCachedThreadPool();
private Processable timeConsumingExternalServiceMock = Mockito.mock(Processable.class);
private SomeTask someTask = new SomeTask();
public ServiceIntegrationTest() {
initializeMocks();
}
private void initializeMocks() {
Mockito.doAnswer(new Answer<Object>() {
public Object answer(InvocationOnMock invocation) throws Throwable {
// Simulation of connection to external services
LOGGER.debug("Sleeping");
Thread.sleep(5000);
LOGGER.debug("Stopped Sleeping");
return null;
}
}).when(timeConsumingExternalServiceMock).process();
// Inject the mock to the Task - in any possible way
someTask.setTimeConsumingExternalService(timeConsumingExternalServiceMock);
}
public void executeTest() {
executorService.execute(someTask);
}
public static void main(String args[]) {
ServiceIntegrationTest integrationTest = new ServiceIntegrationTest();
integrationTest.executeTest();
}
}
And the output to the console:
2012-10-07 22:42:37,378 DEBUG pl.grzejszczak.marcin.SomeTask:21 Before processing
2012-10-07 22:42:37,389 DEBUG pl.grzejszczak.marcin.ServiceIntegrationTest:28 Sleeping
2012-10-07 22:42:42,390 DEBUG pl.grzejszczak.marcin.ServiceIntegrationTest:30 Stopped Sleeping
2012-10-07 22:42:42,392 DEBUG pl.grzejszczak.marcin.SomeTask:23 After processing
Let's take a closer look at the most important part in which an Answer for the execution of the service is being created
Mockito.doAnswer(new Answer<Object>() {
public Object answer(InvocationOnMock invocation) throws Throwable {
// Simulation of connection to external services
LOGGER.debug("Sleeping");
Thread.sleep(5000);
LOGGER.debug("Stopped Sleeping");
return null;
}
}).when(timeConsumingExternalServiceMock).process();
This piece of code changes the default action that should be done by the given object on a given method execution. In this particular case we had to mock a method that returns void - that's why we start with doAnswer(...) and finish with when(...).process().
That is how inside the integration test I managed to create a simulation of waiting for the service to finish. If you have any ideas or comments on how you would do it in another way please feel free to post a comment below :)
And so we code...
Hi! My name is Marcin and I'm a software developer at Rule Financial. Since I'm a coding addict when I'm not coding in Java I'm coding in Java. In addition to that I'm developing websites (including Ryszard Grzejszczak's Lawyer's office, Center for Electoral Studies at University of Lodz, DF Private Financial Advisory). This blog will be about some of the issues that I found in my projects (the majority of those projects you can find on my website) and the ways that I delt with them.
So... To all the coding junkies out there...
So... To all the coding junkies out there...