AdContent.java (EJB3):
@CollectionOfElements
@JoinTable(name="AdContentSites",
joinColumns={@JoinColumn(name="adContentId")})
@Enumerated(EnumType.STRING)
@Column(name="siteName", nullable=false)
@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
SetsiteNames;
public SetgetSiteNames() { return this.siteNames; }
This creates a join table called AdContentSites which maps an AdContent object to one or more SiteName's. SiteName is an enum. I then transform AdContent into a POJO called AdContentData and make that available to the web tier.
This is the transform method:
public static AdContentData adContent(AdContent raw)
{
// Need to lazily initialize the collection
raw.getSiteNames().size();
AdContentData adc = new AdContentData(
raw.getId(),
raw.getName(),
raw.getContent(),
raw.getSiteName(),
raw.getStart(),
raw.getEnd(),
raw.getCreatedBy(),
raw.getCreated());
return adc;
}
The part that bit me in the ass for a while was the fact that Hibernate lazily populates Collections. I kept getting the less than helpful error: "failed to lazily initialize a collection of role: com.kink.heart.entity.adn.AdContent.siteNames, no session or session was closed"
The solution (as you can see above) was to force Hibernate to initialize the Collection by calling AdContent.getSiteName().size(). Maybe it is just me, but I would have expected the call further down to raw.getSiteNames() to do that work for me, but I guess because of the way the object proxy works, that isn't what is going to happen.