Loading...
 

Harezmi IT Solutions Blog

Published by ksevindik on 2016-11-02 ksevindik

One of the nice features of TestContext module of Spring Application Framework is its ability to run unit tests within a transaction context. By that way, you are both able to execute your persistence operations which usually expect an active transaction to run, and able to rollback state changes occur during execution of these persistence operations at the end of the test method invocation. TestContext module also provides you with a mechanism not to rollback, but instead to commit in case you just want to inspect contents of database after the test execution, or populate the database before bootstrapping your application. Following code snippet shows how a unit test method can be made transactional and how default rollback behavior can be switched into commit.

@Test
	@Rollback(false)
	@Transactional
	public void testTransactionalMethod() {
		...
	}

If you invoke a transactional method of a proxy bean within this method, it will inherit transaction context as expected. Following code snippet shows a transactional service method with default propagation (REQUIRED by default) and rollback rules in case an exception is thrown (rollback at RuntimeException, commit otherwise).

@Service
public class TestService {
	@Transactional
	public void test() {
		if(true) throw new RuntimeException("runtime ex to trigger tx rollback");
	}
}


If the transaction propagation behavior of the service method is REQUIRED, then it just continues to work with the same physical transaction which has been started at the beginning of the test method. In case an exception is thrown within that method, Spring transactionManager decides to mark transaction context with setRollbackOnly according to the provided rollback rules.

@Service
@Transactional
public class TestService {
	public void test() {
		if(true) throw new RuntimeException("runtime ex to trigger tx rollback");
	}
}

@Test
	@Rollback(false)
	@Transactional
	public void testTransactionalMethod() {
		testService.test();
	}


In the above code snippet, transaction context is marked with setRollbackOnly when transactional service method throws the RuntimeException. If the transaction context is marked with setRollbackOnly, then Spring TestContext module fails at committing the transaction at the end of the unit test method. However, if the RuntimeException were thrown just outside of the transactional proxy bean, but within the unit test method, transaction initiated by the unit test was going to be committed at the end of the test method invocation.

@Test
	@Rollback(false)
	@Transactional
	public void testTransactionalMethod() {
		if(true) throw new RuntimeException("runtime ex to trigger tx rollback");
	}

This might look as weird a bit if you've expected it to behave similar to the scenario in which a RuntimeException is thrown from within the service method. However, Spring TestContext module just decides on to either commit or rollback the transaction by looking at the @Rollback feedback provided in the test. If there is an explicit commit request via @Rollback(false), then TestContext will just attempt to commit the transaction at the end without considering type of the exception thrown within it!

As a result, you should be aware of such weird behavior in case you decide to make use of integration unit tests to perform database population, and need at some point just to terminate the data population whenever something related with the data population goes wrong. In such a case, you need to throw the RuntimeException just within the transactional service method in order to cause transaction to rollback.

Published by ksevindik on 2016-10-14 ksevindik

Image
As you probably know, JPA provides way to map collection associations using java.util.Map. However, usage scenarios for such mappings are limited, but when it comes, they are invaluable to easily extract necessary information from your domain model. They are especially useful in order to categorize entities in your associated collection based on some unique key property. I prepared two mapping examples in order to show you how java.util.Map can be useful in your projects.
Let's assume you have a Document entity, and it has a description property. However, you have I18n requirements, and you need to store/display different description values based on a given Locale information. Let's also assume that, you need to keep track of changes made on document content each time its content is uploaded from client, for example, store path info for each upload separately. You can store those uploads in another entity, and distinguish among them by using an uploadVersion property. Following code snippet shows that how such a domain model can be created and mapped using JPA.

@Entity
public class Document {
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long id;
	
	@OneToMany(cascade=CascadeType.ALL)
	@MapKey(name="locale")
	@JoinColumn(name="DOC_ID")
	private Map descriptionsByLocale = new HashMap<>();
	
	@OneToMany(cascade=CascadeType.ALL)
	@MapKey(name="uploadVersion")
	@JoinColumn(name="DOC_ID")
	private Map uploadsByVersion = new HashMap<>();
	
...
}


Here above, we've placed @MapKey annotation in addition to @OneToMany annotation in order to map descriptionsByLocale and uploadsByVersion java.util.Map properties. Unless you provide @MapKey with a name property defined in target entity, JPA assumes it will use primary key as identifier by default. We can give any other persistent property which can be used to uniquely identify entities within the mapped collection.

@Entity
public class DocDescription {
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long id;
	
	@Column(name="DOC_LOCALE",unique=true,nullable=false)
	private Locale locale;
	
	private String content;
...
}

@Entity
public class DocUpload {
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long id;
	
	@Column(unique=true,nullable=false)
	private Integer uploadVersion;
	
	private String uploadPath;
...
}


As locale and uploadVersion properties are unique in our DocDescription and DocUpload entities, we can safely make use of them as map keys in our mapping. Finally, we can add getter methods into our Document entity in order to access specific entities based on their keys.

public Collection getDescriptions() {
		return descriptionsByLocale.values();
	}
	
	public DocDescription getDescription(Locale locale) {
		return descriptionsByLocale.get(locale);
	}
	
	public Collection getUploads() {
		return uploadsByVersion.values();
	}
	
	public DocUpload getUpload(Integer version) {
		return uploadsByVersion.get(version);
	}

I hope, those two usage scenarios makes it clear to you when it is useful to make use of @MapKey, and java.util.Map in your domain mappings. Do you have any other usage scenarios for maps?, I'd love to hear...

Published by ksevindik on 2016-09-08 ksevindik
Image


One of the undocumented features of Hibernate is its execution of SQL scripts given within a special file during bootstrap. It is a very useful feature in order to populate your DB with sample data during testing or development mode. If you create a file named import.sql under project's root classpath, and put SQL statements within it, Hibernate is going to execute those statements right after schema export operation.

However, you need to be aware of one or two things while you are using import.sql. First is that, SQL statements you put into that file might be DB specific, therefore you need to replace its contents whenever you change your target DB. Second is that, in order for Hibernate to process this file, its hibernate.hbm2ddl.auto property value should be either "create" or "create-drop".

As you know, we are a big fun of Spring Application Framework, and I want to mention about an alternative but much more flexible way provided by Spring for such sample data population requirements. By using jdbc:embedded-database or jdbc:initialize-database JDBC namespace elements, it's very easy to load sample data not only in application scope, but also specific to each individual test class in your project as well.

<jdbc:embedded-database id="dataSource">
    <jdbc:script location="classpath:schema.sql"/>
    <jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>

<jdbc:initialize-database data-source="dataSource">
    <jdbc:script location="classpath:com/foo/sql/db-schema.sql"/>
    <jdbc:script location="classpath:com/foo/sql/db-test-data.sql"/>
</jdbc:initialize-database>


As we always say that, using Hibernate with Spring in your projects makes things much easier on Hibernate side, and you will become much more productive compared to using Hibernate alone.

Published by ksevindik on 2016-09-05 ksevindik

Image


Spring Security publishes various authentication and authorization events during performing its security checks. Spring managed beans which implement ApplicationListener interface or beans with methods annotated with @EventListener can consume those events within the application. One of those security related events is AuthorizedEvent which indicates that user request is allowed to access secure web resource. It is, however, disabled by default.

In this post, I will try to explain to you how to activate publishing AuthorizedEvents whenever successful authorization occurs within your system. Authorization events are published by FilterSecurityInterceptor bean which is configured by Spring Security element by default. It has a property setter, namely setPublishSuccessAuthorization(..) through which publishing authorization success events are activated. Unfortunately, Spring Security provides no way to pass value to this property within element. There are, however, several ways to change this property value into true and let Spring Security to publish events after successful authorization operation.

One way is not to employ element and configure whose Spring Security filter chain and to configure it and FilterSecurityInterceptor bean via explicit bean definitions. However, that way we lose advantages of configuring Spring Security Filter Chain via security namespace elements.

The other way is a lot easier. It also exploits Spring's event mechanism itself. Here we keep regular Spring Security namespace configuration, and only we need to create a bean which handles Spring's ContextRefreshedEvent. When Spring ApplicationContext is ready to use, ContextRefreshedevent is fired, and we can perform a bean lookup for FilterSecurityInterceptor bean which is implicitly defined via element. When we obtain that bean it is only required to invoke setPublishSuccessAuthorization(..) to enable authorization success events. That's all!

@Component
public class SecurityConfigurer {

	@Autowired
	private ApplicationContext applicationContext;

	@EventListener
	public void handle(ContextRefreshedEvent event) {
		FilterSecurityInterceptor fsi = applicationContext
				.getBean(FilterSecurityInterceptor.class);
		fsi.setPublishAuthorizationSuccess(true);
	}

	@EventListener
	public void handle(AuthorizedEvent event) {
		System.out.println(event.getSource());
		System.out.println(event.getAuthentication());
		System.out.println(event.getConfigAttributes());
	}
}
Published by ksevindik on 2016-04-12 ksevindik

There is always room for improvement in programming. After my initial post about configuring Vaadin in simple 6 steps, my friend indicated that we could use annotation based configuration to get rid of web.xml in our Vaadin configuration. Yes, he is right. It is possible to configure Vaadin with annotations. Let's see how it is;

Step 1: Add Servlet API dependency into your pom.xml, and update your project's configuration

<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>javax.servlet-api</artifactId>
	<version>3.1.0</version>
	<scope>provided</scope>
</dependency>

Step 2: Modify your HelloWorldUI as follows

public class HelloWorldUI extends UI {
	
	@WebServlet(urlPatterns={"/*"},asyncSupported=true)
	@VaadinServletConfiguration(ui=HelloWorldUI.class,productionMode=false)
	public static class ExtendedVaadinServlet extends VaadinServlet {
	}

	protected void init(VaadinRequest request) {
		Button btn = new Button("Click Me!");
		btn.addClickListener(new ClickListener() {
			
			public void buttonclick(ClickEvent event) {
				Notification.show("Hello World!");
			}
		});
		setContent(btn);
	}
}

Step 3: Remove or comment out VaadinServlet configuration in web.xml

Just remove
<servlet> and <servlet-mapping>
elements in web.xml we had added in our previous post.


Now restart your web container, and try to access http://localhost:8080/helloworld URL to see the result. It should work as before.

Published by ksevindik on 2016-04-10 ksevindik

We are highly satisfied with Vaadin UI Framework. I recommend it to anyone who are asking advice about what UI framework to use in their web applications. This article, however, is not about why we love Vaadin. It might be a topic for another article. I will try to show, in this article, how to start working with Vaadin from ground zero super fast. I decided to write about this topic after a message from one of my friends complaining about difficulty in finding his way through Vaadin Book and expressing his confusion about whether using any Vaadin plugin or IDE support is a must to start working with Vaadin. Let's start with step by step.

Step 1: Create a web project using maven webapp archetype

mvn archetype:generate -DgroupId=com.example.vaadin -DartifactId=helloworld -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

Step 2: Import the project into your favorite IDE

I prefer to use Eclipse, but it should not matter whether you use IntelliJ or Netbeans. Just import the maven project you created in the previous step. The project should be ready to use within your favourite IDE after the import.

Step 3: Add Vaadin Dependencies into pom.xml of your project

Add following dependencies into pom.xml file of the project.

<dependency>
	<groupId>com.vaadin</groupId>
	<artifactId>vaadin-server</artifactId>
	<version>7.6.4</version>
</dependency>

<dependency>
	<groupId>com.vaadin</groupId>
	<artifactId>vaadin-client-compiled</artifactId>
	<version>7.6.4</version>
</dependency>

<dependency>
	<groupId>com.vaadin</groupId>
	<artifactId>vaadin-themes</artifactId>
	<version>7.6.4</version>
</dependency>

Step 4: Write UI class in your project

Create a new package with name com.example.vaadin, and following class into it.

package com.example.vaadin;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Notification;
import com.vaadin.ui.UI;

public class HelloWorldUI extends UI {
	protected void init(VaadinRequest request) {
		Button btn = new Button("Click Me!");
		btn.addClickListener(new ClickListener() {
			public void buttonclick(ClickEvent event) {
				Notification.show("Hello World!");
			}
		});
		setContent(btn);
	}
}

Step 5: Configure web.xml file of your project

<servlet>
	<servlet-name>VaadinServlet</servlet-name>
	<servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
	<init-param>
		<param-name>UI</param-name>
		<param-value>com.example.vaadin.HelloWorldUI</param-value>
	</init-param>
</servlet>

<servlet-mapping>
	<servlet-name>VaadinServlet</servlet-name>
	<url-pattern>/*</url-pattern>
</servlet-mapping>

Step 6: Deploy the project into web container and start it


Now you can deploy your project into web container configured in your IDE. I prefer tomcat, but It doesn't differ if you choose jetty or something else. Just type the url your application deployed in the container, e.g. http://localhost:8080/helloworld, and you should have seen the “Click Me!” button on the page.

Keep in mind that above steps are not enough to leverage all the features of Vaadin, however, it is sufficient enough to start working with Vaadin, and develop your server side UI components. You can add necessary pieces into your project once you need them, and it should be easier to add those pieces as you get more comfortable within Vaadin ecosystem.

Published by ksevindik on 2016-03-07 ksevindik

Yakın bir zamanda Beginning Spring isimli kitabımız üzerinden Spring öğrenmeye çalışan bir arkadaşımdan kitapta okudukları sonrasında kafasında beliren böyle bir soru geldi. Kendisine verdiğim cevap belki Spring ile çalışan veya çalışmaya başlayacak arkadaşların da işine yarayabilir düşüncesi ile buradan paylaşıyorum.

Spring ApplicationContext'e hangi sınıfları kullanarak hangi bean'leri oluşturacağını, bu bean'lerin özelliklerinin neler olacağını, bean'ler arasındaki bağımlılıkların bilgisini, ve diğer pek çok uygulama ile ilgili kabiliyeti tanımlamamız gerekiyor. Bu tanımlara "configuration metadata" adı veriliyor. Spring ApplicationContext runtime'da bu configuration metadata'yı işleyerek uygulamanın ihtiyaç duyduğu bean'leri yaratıyor, aralarında ilişkiler kuruyor ve diğer pek çok kabiliyeti hayata geçiriyor.

Configuration metadata farklı formatlarda tanımlanabilir. XML geleneksel yöntemdir, Spring ilk çıktığında sadece XML vardı. Diğer pek çok framework gibi Spring'de konfigürasyon bilgilerini (metadata) XML formatında dosyalardan okuyarak elde ediyordu. O zamanlar daha Java'ya annotation kabiliyeti de eklenmemişti. Java 1.5 veya 5 ile annotation kabiliyeti eklenince bu sefer framework'ler arasında konfigürasyon metadata tanımlama yöntemi olarak annotation kullanma furyası başladı. Spring'de bu dönemde XML'in yanına bir de annotation kullanarak bean tanımlama, bean'ler arasındaki bağımlılıkları enjekte etme gibi kabiliyetler ekledi.

Tabi burada Spring ekibi şunu da sağlamıştır. ApplicationContext metadata formatından bağımsız tutularak, ApplicationContext'i ister XML, ister annotation tabanlı konfigüre etmek mümkün kılınmıştır. Hatta bu metadata formatlarını bir arada aynı anda kullanarak da ApplicationContext konfigürasyonu yapılabilir. Ancak burada şuna da dikkat etmek gerekiyor. Annotation tabanlı konfigürasyon XML tabanlı konfigürasyonun bire bir kopyası veya alternatifi olacak seviyede veya kabiliyette değildir. Aslında annotation tabanlı konfigürasyon XML tabanlı konfigürasyonla birlikte kullanılacak, onu complement edecek biçimde şekillendi. Günümüzde Spring kullanan projelerde de XML ve annotation tabanlı konfigürasyonlar çoğunlukla birlikte kullanılır. Spring'e özel altyapısal kabiliyetlerin konfigürasyonu veya uygulama koduna ait olmayan sınıflardan bean tanımları XML ile yapılırken, uygulamaya özel sınıflardan bean tanımları ve bağımlılıkların enjeksiyonu ise @Component, @Service, @Repository, @Controller, @Autowire gibi annotasyonlar kullanılarak annotasyon tabanlı gerçekleştirilir.

Zaman içerisinde XML tabanlı konfigürasyonlarla ilgili type safety, refactor edilebilirlik, modülerlik, extend edilebilirlik gibi noktalarda eleştirilerden dolayı bu sefer de framework'lerde Java tabanlı konfigürasyon popülerlik kazandı. Spring'de bu akıma ayak uydurdu ve XML tabanlı konfigürasyon ile yapılan işlemlerin bire bir aynısını Java sınıfları, metotlar ve bunların üzerinde bazı annotasyonları kullanarak yapmayı sağladı. Doğalarından ötürü kullanım biçimlerinde, davranışlarında bazı farklar olsa da, Java tabanlı konfigürasyona XML tabanlı konfigürasyonun bire bir alternatifi diyebiliriz. Tabi Spring ekibi ApplicationContext konfigürasyonunu daha önceden metadata formatından bağımısz kıldığı için bu davranışı Java tabanlı konfigürasyonda da korumuştur.

Spring uygulamalarında aynı anda hem XML, hem @Component, @Autowire gibi annotasyonlar, hem de Java konfigürasyon sınıfları ile ApplicationContext konfigürasyonu yapmak mümkündür. Artık günümüzde Servlet 3 API'sindeki yeniliklerle birlikte hiç Spring XML dosyalarına ve web.xml dosyasına ihtiyaç duymadan Spring kabiliyetine sahip web uygulamalarının konfigürasyonu yapılabilmektedir.

Published by ksevindik on 2016-03-01 ksevindik

Recently I had a chance to spend some time reading about OData and experiment with Apache OLingo Project in order to understand what OData provides us with in terms of making our REST services more standardized and self discoverable. I also compared it with Spring Data REST Project, what are their similarities and differences, whether it would be meaningful to integrate OLingo with Spring REST, or what should be the scope of integration if possible.

OData is simply a data exchange protocol by definition, and it tries to operate over REST. As it is a data exchange protocol, it first starts with defining a metamodel called as entity data model (EDM). Within EDM, we first specify what are our entities, what attributes they contain, what associations exist between them, functions which can be performed over those entities and so on.

public class PetClinicEdmProvider extends CsdlAbstractEdmProvider {
@Override
	public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODataException {
CsdlEntityType entityType = new CsdlEntityType();
entityType.setName(ENTITY_TYPE_NAME_VET);

CsdlPropertyRef idRef = new CsdlPropertyRef();
idRef.setName("id");


CsdlProperty id =  new CsdlProperty().setName("id").setType(EdmPrimitiveTypeKind.Int64.getFullQualifiedName());
CsdlProperty firstName = new CsdlProperty().setName("firstName")
		.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
CsdlProperty lastName = new CsdlProperty().setName("lastName")
		.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
CsdlProperty graduationYear = new CsdlProperty().setName("graduationYear")
		.setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());

entityType.setProperties(Arrays.asList(id,firstName, lastName, graduationYear));
entityType.setKey(Arrays.asList(idRef));

CsdlNavigationProperty navigationProperty = new CsdlNavigationProperty();
navigationProperty.setName("Specialties"); //name of the navigation property
navigationProperty.setType(FQN_ENTITY_TYPE_SPECIALTY);
navigationProperty.setNullable(false);
navigationProperty.setCollection(true);
navigationProperty.setPartner("Vets");

entityType.setNavigationProperties(Arrays.asList(navigationProperty));

return entityType;
}
}


After creating EDM, it comes to write Processor objects to expose data and handle navigations between entities, perform CRUD operations or other functions/actions and data filtering through REST. We can easily say that Processor objects closely corresponds with RestController beans in Spring MVC REST. They handle incoming web request, extract information out of it and translate that OData specific information into a format so that current task can be delegated to business layer. After business layer returns, this time domain specific result data is translated back into the OData format and web response is generated by writing it as response body. That translator part as depicted in the below diagram is called as OData service gateway or gateway in short. It acts as a bridge between processor layer and service layer.

public class PetClinicEntityProcessor implements EntityProcessor {
@Override
public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
		throws ODataApplicationException, ODataLibraryException {
	// extract metadata from request uri
	List resourceParts = uriInfo.getUriResourceParts();
	UriResource uriResource = resourceParts.get(0);
	UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriResource;
	EdmEntitySet edmEntitySet = resourceEntitySet.getEntitySet();

	// extract query data from request uri to perform search
	List keyPredicates = resourceEntitySet.getKeyPredicates();

	// execute backend business logic, search for specific entity in this
	// case
	Entity entity = oDataServiceGateway.readEntity(edmEntitySet, keyPredicates);

	// create a serializer to serialize found entity
	ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();
	EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build();
	ODataSerializer serializer = odata.createSerializer(responseFormat);
	SerializerResult result = serializer.entity(serviceMetadata, resourceEntitySet.getEntityType(), entity,
			options);

	// write serialized data into the response
	response.setContent(result.getContent());
	response.setStatusCode(HttpStatusCode.OK.getStatusCode());
	response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
}
}


Image

Finally, you need to write an ODataServlet in which you bring those pieces together and handle current web request. ODataServlet, Processors and OData service gateway can be seen as composing a Controller layer altogether.

public class ODataServlet extends HttpServlet {
    
    private PetClinicService petClinicService = new PetClinicServiceImpl(new PetClinicDaoInMemoryImpl());
    
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		OData oData = OData.newInstance();
		ServiceMetadata serviceMetadata = oData.createServiceMetadata(new PetClinicEdmProvider(), new ArrayList&lt;&gt;());
		ODataHttpHandler handler = oData.createHandler(serviceMetadata);
		
		ODataServiceGateway oDataServiceGateway = new ODataServiceGateway(petClinicService);
		PetClinicEntityCollectionProcessor entityCollectionProcessor = new PetClinicEntityCollectionProcessor(oDataServiceGateway);
		PetClinicEntityProcessor entityProcessor = new PetClinicEntityProcessor(oDataServiceGateway);
		PetClinicPropertyPrimitiveProcessor propertyPrimitiveProcessor = new PetClinicPropertyPrimitiveProcessor(oDataServiceGateway);
		
		//handler.register(new DefaultDebugSupport());
		handler.register(entityCollectionProcessor);
		handler.register(entityProcessor);
		handler.register(propertyPrimitiveProcessor);
		
		handler.process(request, response);
    }
}


Image

The end result is just exposing domain/data model over REST in a standard format/structure. OData specification tries to act similar to WSDL/SOAP of REST world. We can actually say that OData is WSDL/SOAP of REST. In my experience, it seems that as WSDL/SOAP makes things too complex in XML based web services, same is true for OData in REST side. Although, it will help you expose your domain/data model in a standard format, and make it exchangeable among various clients and server, if your expectation from OData is just to create a standard REST API for accessing data, and performing operations over REST, OData will simply be an overkill.

Spring Data REST and OData/OLingo are competitors. They both are trying to achieve similar results but from completely different perspectives. As OData is totally data centric or data oriented, Spring Data REST, on the other hand, is function oriented. It would be meaningless trying to integrate OData/OLingo with Spring Data REST or Spring MVC REST so that Spring should totally be responsible in handling web requests, and operating on controller layer. OData as protocol, and Apache OLingo as implementation of it should be in complete control in handling web requests. However, OLingo can be integrated with Spring and leverage Spring Container's capabilities in a limited fashion. ODataServlet can be replaced with a Spring Controller which just handles any HTTP request and delivers it to OData Handler for further processing. Response is not written by Spring at all. OData service gateway can be made a Spring managed bean. That way, Spring managed service beans can easily be injected into it.

@Controller
public class PetClinicODataController {
	
	@Autowired
	private PetClinicService petClinicService;
	
	@RequestMapping
	public void handle(HttpServletRequest request, HttpServletResponse response) {
		//OData instance must be unique for each request/thread
		OData oData = OData.newInstance();
		
		ServiceMetadata serviceMetadata = oData.createServiceMetadata(new PetClinicEdmProvider(), new ArrayList&lt;&gt;());
		ODataHttpHandler handler = oData.createHandler(serviceMetadata);
		
		ODataServiceGateway oDataServiceGateway = new ODataServiceGateway(petClinicService);
		PetClinicEntityCollectionProcessor entityCollectionProcessor = new PetClinicEntityCollectionProcessor(oDataServiceGateway);
		PetClinicEntityProcessor entityProcessor = new PetClinicEntityProcessor(oDataServiceGateway);
		PetClinicPropertyPrimitiveProcessor propertyPrimitiveProcessor = new PetClinicPropertyPrimitiveProcessor(oDataServiceGateway);
		
		handler.register(new DefaultDebugSupport());
		handler.register(entityCollectionProcessor);
		handler.register(entityProcessor);
		handler.register(propertyPrimitiveProcessor);
		
		handler.process(request, response);
	}
}


Spring Data REST's choice to make REST API standardized and self discoverable is HATEOAS. Hypertext as engine of application state is an approach so that clients should be able to discover REST API by themselves via following HTML link tags returned from REST service calls. However, even with HATEOAS, everything is not explicitly defined and self discoverable by client applications without any external help. It is still needed for someone who will interpret returned links and prepare upcoming REST calls out of those link information. On the other hand, it is necessary to have a standardized approach or style applied throughout a REST API. That way, client side developers will easily understand and learn how to fetch, insert, update or delete data.

Published by ksevindik on 2016-02-17 ksevindik

Factory method pattern aims to encapsulate object creation process within a method. That's why it is called as factory method pattern. They can be created as either static or instance methods within a class. In Spring Application Framework, although it is possible to make use of static or instance factory methods to create Spring managed beans, Spring offers an interface FactoryBean for this purpose. It has following contract:

public interface FactoryBean<T> {
	T getObject() throws Exception;
	Class<?> getObjectType();
	boolean isSingleton();
}


Whenever we need to encapsulate an object creation logic, we just implement this interface and create the target object within getObject() method.

public class FooFactoryBean implements FactoryBean<Foo> {

	@Override
	public Foo getObject() throws Exception {
		return new Foo();
	}

	@Override
	public Class<?> getObjectType() {
		return Foo.class;
	}

	@Override
	public boolean isSingleton() {
		return true;
	}

}


getObject() method is in role of factory method in that case. getObjectType() method just returns type of the instance we are creating. isSingleton() says whether the object managed by the Spring is singleton or not. If it's singleton, that means getObject() returns always the same instance, and Spring Container can cache it.

Afterwards, we define our bean and give FQN of our FactoryBean implementation class instead of our target bean class as follows;

<bean id="foo" class="examples.FooFactoryBean"/>


During bootstrap process, Spring Container pays special attention to the bean definitions whose classes implement FactoryBean interface. Whenever it sees a FactoryBean class, it creates an internal bean from that class, but also invokes its getObject() method and make the returned instance as the actual bean. Therefore, following code block can be used to obtain a reference to the Foo object;

Foo foo = applicationContext.getBean(Foo.class, "foo");


However, sometimes you may need to access to the FactoryBean instance of "foo" bean instead. Spring provides a special operator "&" for this purpose. If you perform your bean lookup with "&foo", then ApplicationContext will return you the FooFactoryBean instance. It look similar to referencing addresses of variables in C! Another option to access FooFactoryBean instance is to perform lookup by type, as follows;

FooFactoryBean fooFactoryBean = applicationContext.getBean(FooFactoryBean.class);


Of course, above will only work, if there is only one bean definition of type FooFactoryBean in the ApplicationContext.

By default, beans defined in the Spring Container are initialized eagerly during bootstrap unless they are marked as lazy, and FactoryBean instances are, too. However, FactoryBean.getObject() method is not invoked until target bean is actually needed or accessed even its bean definition is kept as eager.
If you want your bean to be initialized even it is not accessed or injected into another bean, then you need to implement another interface from Spring Application Framework, which is called as SmartFactoryBean.

public interface SmartFactoryBean<T> extends FactoryBean<T> {
	boolean isPrototype();
	boolean isEagerInit();
}


SmartFactoryBean is actually a sub type of FactoryBean interface. It declares two methods. One is isPrototype(), which indicates returned instances from getObject() method are always independent from each other. That means, they are prototype in Spring terminology. The other method is what we seek for. isEagerInit() method can be used to indicate that target bean should be eagerly initialized during bootstrap.

Published by ksevindik on 2016-01-18 ksevindik

Spring documentation states that both autowire byType and constructor modes expect at most one bean definition in the ApplicationContext, so that it can be autowired into the depending bean. Here is the excerpt taken from Spring Reference Documentation Table 6.2. Autowiring modes;

byTypeAllows a property to be autowired if exactly one bean of the property type exists in the container. If more than one exists, a fatal exception is thrown, which indicates that you may not use byType autowiring for that bean. If there are no matching beans, nothing happens; the property is not set.
constructorAnalogous to byType, but applies to constructor arguments. If there is not exactly one bean of the constructor argument type in the container, a fatal error is raised.


However, they don't show exact behaviour if there are more than one bean in the ApplicationContext and name of one of those beans matches with the name of constructor parameter. Let's see what is the difference with the following code samples;

First, XML based configuration

public class Foo {
	private Bar bar;

	public void setBar(Bar bar) {
		this.bar = bar;
	}
	
	public Bar getBar() {
		return bar;
	}
}

<beans...>
	<bean id="foo" class="examples.Foo" autowire="byType"/>
	
	<bean id="bar1" class="examples.Bar"/>
	
	<bean id="bar2" class="examples.Bar"/>
</beans>


The above sample will produce following error as expected:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [examples.Bar] is defined: expected single matching bean but found 2: bar1,bar2


Now we change the Foo class so that Bar is to be injected as a constructor parameter, change autowire mode to constructor, and give a try;

public class Foo {
	private Bar bar;

	public Foo(Bar bar) {
		this.bar = bar;
	}
}

<beans...>
	<bean id="foo" class="examples.Foo" autowire="constructor"/>
	
	<bean id="bar1" class="examples.Bar"/>
	
	<bean id="bar2" class="examples.Bar"/>
</beans>


As expected, we got the same error as above;

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [examples.Bar] is defined: expected single matching bean but found 2: bar1,bar2


Now, here comes the difference. When we add another name one of those two Bar beans with an element, for example, autowire="constructor" starts working! It injects the bean with name matching with the name of the constructor parameter.

<beans...>
	<bean id="foo" class="examples.Foo" autowire="constructor"/>
	
	<bean id="bar1" class="examples.Bar"/>
	
	<bean id="bar2" class="examples.Bar"/>

	<alias name="bar2" alias="bar"/>
</beans>


Practically, autowire="constructor" turns into "byName", in which it is stated that only bean with the matching name is injected. However, when we run the code with autowire="byType", it still gives the error as listed above.

Now, annotation based configuration


At this point, let's give annotation based configuration a try, and see what happens there as well.

@Component
public class Foo {
	private Bar bar;

	@Autowired
	public Foo(Bar bar) {
		this.bar = bar;
	}	
}

<beans...>
	<context:component-scan base-package="examples"/>
	
	<bean id="bar1" class="examples.Bar"/>
	
	<bean id="bar2" class="examples.Bar"/>

	<alias name="bar2" alias="bar"/>
</beans>


When @Autowired annotation is placed on constructor, it works as expected.

Now, I change the code so that autowire will be performed with setter injection as follows;

@Component
public class Foo {
	private Bar bar;
	
	@Autowired
	public void setBar(Bar bar) {
		this.bar = bar;
	}
	
	public Bar getBar() {
		return bar;
	}
}


I would expect it wouldn't work when @Autowired annotation is placed over setter method, but, it works!

Unfortunately, the result of xml based autowiring with byType mode prevents us from concluding that autowire byType and constructor modes give precedence to bean name - property/constrcutor parameter name correspondence when more than one bean of matching type found in the ApplicationContext. There is clearly a behavioural inconsistency between xml based and annotation based autowiring in Spring.