Thursday, March 25, 2010

Security Questions

I hate the sites that require you to insert the security question that must be chosen out of an enumeration. My problem with an enumeration is simple: most of the answers to these questions can be googled very easily (in my case they extremely easily if you are Russian speaking).
It's very easy to know what primary school I've attended, which city I currently live in (or was born) and what is my nickname.
Why is it such a difficult task to allow custom security questions? After all these questions intend to provide a security and not a security breach...

Wednesday, March 24, 2010

Hibernate/JPA Best Practices

Here come some of Hibernate/JPA best practices.
Please notice that this guide does not intend to cover Hibernate/JPA at all, but only to provide some best practices. Personally I learned Hibernate using Hibernate in Action.

I really appreciate any comments saying what do you think about this practice, why it's wrong, and what additional practices should be added.

So let's start:

Override hashCode() and equals()

The Hibernate reference states that "It is recommended that you implement equals() and hashCode() to compare the natural key properties of the entity."
The reason is simple: different instances of the class may represent the same record in the database. Therefore, when comparing these two instances, you'd like to get equal result, while default equals implementation will return not-equal since it's not the same instance.

This becomes really important, when working with collections, especially with Sets. You don't want the same object to appear twice in set, right?

Overriding the hashCode() and equals() is not a very complex goal, but you must be very careful:
1. Remember that two equal objects must return the same hash code. Therefore, you cannot use auto-generated Hibernate id in hashCode() - this value is not assigned for the newly created objects. After persistence occurs, the value is assigned, so the hashCode will change, when the object actually wasn't changed!
2. Changing the fields that participate in hashCode() will change the hash code value. So if your object is stored in a Set (or it's key of a Map), you won't be able to retrieve it from the set anymore - one hash was used for insert and another one was used for retrieve.
So basically you'll need to remember not to change objects that are stored in sets! And this is really important!
So you may ask: how will I know who stored my object in a set?
My answer is simple: you cannot know this, unless you don't give your objects out. So you are the only person who is using these objects, so you know how they are kept, right?
Storing the objects without giving them out is not so weird idea: keep the persistence layer away from the business logic and return a copy of object when required.
Another option: return immutable objects to the business tier. So the business tier won't be able to change them. When the change is required - provide a special API. Thus the objects won't change accidentally.

Try to Make All Object Immutable

This may sound weird, how exactly the persistent objects can be immutable. But in the previous part I described why it's important. And actually it can be quite easily achieved:
1. Make all setters private. Thus it will be impossible to call them without using reflection. (Hibernate will use reflection and populate the properties during the object retrieval)
2. When returning collections, wrap them with Collections.unmodifiable. So the user won't be able to modify your collections.
3. Allow changes only via special methods.

Return Copy of Persistent Objects to the Business Tier

So no accidental change in hash code may occur.
Additionally when filling the business objects, a lot of potential problems may be resolved. Consider that the persistent object contains a lazy collection. If the object is returned as is to the business tier, the lazy elements in the collections can be accessed after the transaction was closed, therefore the query to the database will fail and user will get an exception.

h3. Change Data in Collections Only via Special Methods
When having associations, take care of this association via special method: for example, Parent class will have method addChild(Child child).
When returning the values of collections wrap them using Collections.unmodifiable to prevent accidental changes.
This is useful both to handle bidirectional associations correctly and to prevent accidental changes in hash code.

Summary

1. Override hashCode() and equals() of the entities using the natural key properties of the entity.
2. Don't compare auto-generated id in hashCode().
3. Don't change the properties that participate in the hashCode() for objects stored in collections that use hash code (especially Sets or Maps). If such a change must occur, reinsert object into collection. Remember that remove must occur before the property is updated.
4. Keep the persistence tier away from the business logic as much as possible. Don't pass the persistence objects to the business at all.
5. Make your objects immutable (or semi-immutable): make all setters private, return collection values only wrapped with Collections.unmodifiable, make changes in collections only via special methods.


Recommended Reading

1. Hibernate in Action (In Action series)
2. Java Persistence with Hibernate
3.The Best Software Writing I: Selected and Introduced by Joel Spolsky (v. 1)

Sunday, March 7, 2010

Maven: Copy Dependencies to a folder

So if you need to copy all project dependencies to a folder using Maven, just type
mvn dependency:copy-dependencies -DoutputDirectory=<folder name>

Can it be more simple?
So why I'm googleing for it over and over again?


Recommended Reading

1. Maven: The Definitive Guide
2. Pro Git
3. Smart and Gets Things Done: Joel Spolsky's Concise Guide to Finding the Best Technical TalentProgramming Language & Tool Books)

Tuesday, March 2, 2010

Apache Wink - Dynamic Resources

Quite often people ask me what is so different about Apache Wink, and why another JAX-RS framework. Usually I answer that Apache Wink started in HP long before there was any REST open-source framework. It was developed internally for two years before joining Apache.

This may be interesting from historical point of view, but then people ask: so why should we use it now? Are there any unique features?
And the answer here is: yes, there are some unique features beyond the JAX-RS spec and this post will describe one of the most cool features (IMO) that Wink contains:

Dynamic Resources


The idea of Dynamic Resource is quite similar to Template pattern and it's simple: many resource classes have more or less the same logic. However, they manipulate different entities, so obviously they have different URLs.

Consider the following example: a resource that simply a facade to the database - it allows the CRUD operation and it uses Hibernate as the persistence layer.

So basically the template class will look something like this:

public class CrudResource {

private Session session;
@Context
private UriInfo uriInfo;

private Class clazz;

@GET
public Object getEntity(@PathParam("id") String id) {
return session.get(clazz, id);
}

@POST
public Response createEntity(Object newEntity) {
session.save(newEntity);
String id = newEntity.getId(); // this line will not compile, but the idea is that id is assigned by hibernate
URI location = uriInfo.getAbsolutePathBuilder().segment(String.valueOf(id)).build();
return Response.created(location).build();
}

@PUT
public void updateEntity(Object entity) {
session.update(entity);
}

@DELETE
public void delete(@PathParam("id") String id) {
session.delete(session.get(clazz, id));
}

}

Notice: This class doesn't contain the full logic, like transaction management, and won't even compile. It should provide the idea how to implement the "template" style resource and not how to really work with Hibernate or even Wink.

So as you can see, this class can basically perform the CRUD operations on any entity. It would be a pity, if for each entity, we'll need to extend this class just to assign a different path. And here come the Dynamic Resources. They allow to skip the @Path annotation and implement the DynamicResource interface instead (or extend from the AbstractDynamicResource class).

So now our resource will look something like this:
public class CrudResource extends AbstractDynamicResource  {
...
}

Now it's possible to create multiple instances of this class and assign it a different paths and other members (like 'clazz', which should hold the value of actual class).

Notice: Dynamic Resources can be returned only by Application.getSingletons() method. Thus these resources are actually singletons and must be coded accordingly (for example think about synchronization issues).

Spring Integration


Wink contains the Spring Integration extension. I won't describe its features here, but only want to mention the usage of Dynamic Resources with Spring.
First, Dynamic Resource can be defined and registered via Spring Context, thus you can create new resources using the same class, while updating the configuration only. Pretty nice feature, when you think about it.
Second, Dynamic Resources benefit from different scopes. Meaning, they may not be singletons anymore.