Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way to initialize collection of an entity (POJO) in Spring-Hibernate project?

I have a POJO class, say Foo, which has a Set of other entity instances, say bars. Also there are standart misc classes for such project: service and dao for both Foo and Bar.

I want BarService to get the Set of Bar instances associated with some Foo. Now I have the following code, wich I believe is conceptually bad.

 
public class Foo {
    Set<Bar> bars;

    public Set<Bar> getBars() {
        if (bars == null)
            return ( bars = new HashSet() );
        return bars;
    }
}
 
public class BarServiceImpl {
    public List<Bar> getListOfBars(Foo foo) {
        return new ArrayList(foo.getBars());
    }
}

3 questions: Where it is better to initialize Foo's Set? What specific Sets and Lists are better for such purposes? What conceptual issues has my current implementation, and how to do better?

Thanks in advance.

like image 949
edio Avatar asked Oct 29 '10 08:10

edio


People also ask

What is Hibernate POJO?

POJO classes are used in hibernate for mapping to database objects. That means all object entities we make in POJO classes will be reflected in a database object. It should not extend classes, implement interfaces, or contain prespecified annotations.

How to initialize Proxy in Hibernate?

Hibernate. initialize(entity. getXXX()) will force the initialization of a proxy entity or collection entity. getXXX() as long as the Session is still open.


1 Answers

Where it is better to initialize Foo's Set?

Most of time, I initialize a collections when declaring it, which is what Hibernate recommends. Quoting the documentation:

6.1. Persistent collections

Hibernate requires that persistent collection-valued fields be declared as an interface type. For example:

public class Product {
    private String serialNumber;
    private Set parts = new HashSet();

    public Set getParts() { return parts; }
    void setParts(Set parts) { this.parts = parts; }
    public String getSerialNumber() { return serialNumber; }
    void setSerialNumber(String sn) { serialNumber = sn; }
}

The actual interface might be java.util.Set, java.util.Collection, java.util.List, java.util.Map, java.util.SortedSet, java.util.SortedMap or anything you like ("anything you like" means you will have to write an implementation of org.hibernate.usertype.UserCollectionType.)

Notice how the instance variable was initialized with an instance of HashSet. This is the best way to initialize collection valued properties of newly instantiated (non-persistent) instances. When you make the instance persistent, by calling persist() for example, Hibernate will actually replace the HashSet with an instance of Hibernate's own implementation of Set.

If leaving it null is part of your business, my suggestion would be to initialize it in a (common) link management methods:

public class Foo {
    ...
    private Set<Bar> bars;
    ...
    public void addBar(Bar bar) {
        if (this.bars == null) {
            this.bars = new HashSet<Bar>();
        }
        this.bars.add(bar);
    }
}

What specific Sets and Lists are better for such purposes?

It all depends on the semantics you need. A Set doesn't allow duplicates, a List allows duplicates and introduces positional indexing.

What conceptual issues has my current implementation, and how to do better?

  1. I wouldn't perform an assignment in the getter.
    • If a collection is supposed to be null at that point, let it be null.
  2. I don't see the added value of your service
    • why not just calling foo.getBars()?
    • why converting the collection?
like image 131
Pascal Thivent Avatar answered Nov 14 '22 23:11

Pascal Thivent