简体   繁体   中英

Should persistent classes initialize instance variable collections

In my Hibernate classes should instance collections be initialized

public class Basket {
    private List items = new ArrayList();

    ...getters and setters...
}

or left uninitalized

public class Basket {
    private List items;

    ...getters and setters...
}

does it make any kind of difference for Hibernate? I came across this Hibernate documentation where it initializes their HashSet, but I have often seen them left uninitialized.

Doing static initialization as in your first code block cuts down on the need for null checking, and if you know that you'll be using the collection in the majority of use cases, it makes sense.

If, on the other hand, the collection is rarely used, it makes more sense to defer initialization until you actually need to use it.

From Hibernate's persistent collection documentation:

Due to the underlying relational model, collection-valued properties do not support null value semantics. Hibernate does not distinguish between a null collection reference and an empty collection.

And ...

When you make the instance persistent, by calling persist(), Hibernate will actually replace the HashSet with an instance of Hibernate's own implementation of Set.

These "non-null collection" and "persistent" versus "non-persistent" semantics sometimes gets lost with developers. To keep things simple with Hibernate objects, I prefer:

  • always initialize all Collections with java.util implementations
  • always code to Collection interfaces

Making it customary for Hibernate object Collection s never being NULL and avoiding the pitfall noted in the above documentation of casting a Hibernate object Collection to an invalid implementation.

You should initialize it. Even if Hibernate where to initialize it later even if it had no content (which I'm not sure it's always the case), you should initialize it to be sure that it's always coherently not-null.

In the provided example you can see that Cat has no explicit no-argument constructor, so they have to initialize the set at declaration. Most likely when you see it left uninitialized there was also an explicit no-arg constructor that initialized it later.

I cannot back it up with any sort of professional documentation, but here is my opinion on that matter. I think you have two possible roads to follow.

DTOs only

The first one relies on Model beans to be plain DTOs, used only for data persistence, performing no logic. Here you can leave your POJO fields uninitialized , since that will be done automatically by Hibernate before you'll retrieve persistent object via Session. I'm sure you already know, that Hibernate will silently wrap all collections into it's own wrappers, which is needed by internal persistence mechanism.

Proper model classes

The second approach takes POJOs a little bit further. In this scenario you can perform some logic within the getters and setters methods. This is not that uncommon scenario, after all it's perfectly acceptable by MVC and very often one would find himself in need of adding some code to them. For instance - logging some information while calling setter method, example below:

public void setItems(List<Object> items){
   LOGGER.info("Setting '{}' new items", items.size());
   this.items = items;
}

In that case, one could fell into trouble, since as far as I know the collection will not be initialized by Hibernate at this point. In that case explicit initialization would be better.

Final remark: I'm not the expert on Hibernate, I also do not know if anything has changed in 4.x, but I know I endured this problem at some point.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM