November 26 2013 by Kevin Bowersox

The following tutorial details how to use the @Inheritance annotation in JPA to map an inheritance relationship in an object model.  The tutorial discusses the capabilities provided by @Inheritance that are absent when utilizing the @MappedSuperClass annotation.  Appropriate use of both annotations is further discussed.

 

To follow along, download the base code used for this tutorial from this GitHub repository. Source code for the completed project can be downloaded by clicking the GitHub logo below.

Continue Reading
May 31 2013 by Kevin Bowersox

The following tutorial details how to use the Spring Data to query against an object model. The tutorial explains how to define various interface methods on Spring Data Repositories that account for specific criteria and ordering. To follow along download the base code used for this tutorial from this Git Hub Repository. Source code for the completed project can be downloaded by clicking the GitHub logo below.

Continue Reading
May 24 2013 by Kevin Bowersox

The following tutorial details how to use the JPA Criteria API to query against an object model. The tutorial explains how to create a simple, joined and aggregate query using the Criteria API. To follow along download the base code used for this tutorial from this Git Hub Repository. Source code for the completed project can be downloaded by clicking the GitHub logo below.

Continue Reading
May 05 2013 by Kevin Bowersox

This morning while working on a new project, I needed to configure some advanced data-binding using Spring MVC.  In a nutshell, I needed to convert a String provided by the request to an instance of an entity.  After a few minutes of research, I discovered that Spring's org.springframework.core.convert.converter.Converter was the tool for the job.  The proceeding post will discuss the creation and configuration of a Converter.

First, let's discuss the context.  I had two entities, Client and TwitterAccount that shared a bidirectional relationship.

 

Client.java

@Entity
@Table(name = "CLIENT")
public class Client {
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="CLIENT_ID")
	private Long clientId;
		
	@OneToOne(cascade=CascadeType.ALL, mappedBy="client")
	private TwitterAccount twitterAccount;
}

 

TwitterAccount.java

@Entity
@Table(name="TWITTER_ACCOUNT")
public class TwitterAccount {

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="TWITTER_ACCOUNT_ID")
	private Long twitterAccountId;
		
	@OneToOne(cascade=CascadeType.ALL)
	@JoinColumn(name="CLIENT_ID")
	private Client client;
}

On the client.jsp page I was attempting to create or update a TwitterAccount using the form below.  Notice that I was including the clientId field in a hidden input so the client could be associated with the account during data persistence in the controller.

 

Client.jsp

<form action="<c:url value="/twitter/save" />" method="post">
   	<fieldset>
	   	<legend> Account Details </legend>
   	   	<!--Account Fields -->					
	</fieldset><br/>
	<button type="submit" class="btn btn-primary">Submit</button>
	<input type="hidden" name="client" value="${client.clientId }"/>
</form>

In my controller, I data-bound the TwitterAccount using @ModelAttribute, causing associated parameters to be mapped to fields on the TwitterAccount instance.  One major challenge was converting the String parameter clientId to an object of type Client.  I wanted the Client field within TwitterAccount to be automatically assigned the Client associated with the clientId parameter in the request.  Although powerful, Spring MVC is not capable of binding custom objects in this manner, which is understandable.

 

TwitterAccountController.java

	@RequestMapping("/save")
	public String save(@ModelAttribute TwitterAccount account, 
             BindingResult bindingResult){
		accountService.save(account);
		return "redirect:/clients/";	
	}

To perform the desired data-binding, I needed to create a new Converter that converted the String parameter clientId to the appropriate instance of Client.

 

StringToClientConverter.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.converter.Converter;

import com.network.socially.data.entities.Client;
import com.network.socially.data.repositories.ClientRepository;

public class StringToClientConverter implements Converter<String, Client> {

	@Autowired
	ClientRepository clientRepository;
	
	@Override
	public Client convert(String source) {
		return clientRepository.findOne(new Long(source));
	}

}

With the converter created the final step was to register the converter in the configuration for my dispatcher servlet.  This was done by adding a bean of type ConversionServiceFactoryBean to the configuration and supplying the Converter in its list of parameters.  The newly created ConversionServiceFactoryBean then needed to be specified in the mvc:resources tag.

 

dispatcher-context.xml

<mvc:annotation-driven conversion-service="conversionService"/>
	
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <list>
            <bean class="com.network.socially.web.converters.StringToClientConverter"/>
        </list>
    </property> 
</bean>  

 

Continue Reading
May 03 2013 by Kevin Bowersox

While configuring an upcoming project I experienced an issue that was caused by a conflict between Spring MVC and Spring Data.  My pom.xml file contained the following dependencies:

  <dependencies>
  	<dependency>
  		<groupId>org.springframework</groupId>
  		<artifactId>spring-webmvc</artifactId>
  		<version>3.2.2.RELEASE</version>
  	</dependency>
  	<dependency>
  		<groupId>org.springframework.data</groupId>
  		<artifactId>spring-data-jpa</artifactId>
  		<version>1.3.0.RELEASE</version>
  	</dependency>
  </dependencies

This caused the following exception to be thrown when I ran the application:

Caused by: java.lang.IncompatibleClassChangeError: class org.springframework.core.type.classreading.ClassMetadataReadingVisitor has interface org.springframework.asm.ClassVisitor as super class
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
	at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2904)
	at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1173)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1681)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
	at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2904)
	at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1173)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1681)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
	at org.springframework.core.type.classreading.SimpleMetadataReader.(SimpleMetadataReader.java:63)
	at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:80)
	at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:102)
	at org.springfr

 

After some investigation I learned that the exception was thrown due to a conflict between the version of Spring AOP used by the two projects.

To resolve the issue, I accessed the Dependency Hierarchy in the pom.xml file and located the spring-aop:3.2.2.RELEASE dependency.  I then right clicked this dependency and click Lock Transitive Dependency Version.

Continue Reading
Next 5 Entries Previous 5 Entries