Q:

How can I load a Hibernate-mapped set as an unmodifiable set?

An application I'm working on uses Hibernate exclusively to fetch a bunch of persistent objects from a database to memory. The application is to refresh this in-memory snapshot from the database every now and then, and that should be the only communication with the database.
The in-memory objects are then used for a bunch of calculations. The calculations must not modify these objects. Except some class somewhere accidentally did, and I had to spend a day hunting down the bug. Now I'm wondering what the best way to make the entire object tree immutable is.
Suppose the class hierarchy looks like this:
public class Building { // persistent entity
    private String name; // hibernate-mapped property
    private Set<Person> inhabitants; // hibernate-mapped collection

    // getters
}

public class Person { // persistent entity
    private String name; // hibernate-mapped property

    // getters
}

I've prevented clients from accessing the database by:

eagerly fetching all entities and collections
marking all entities and collections with mutable=false in Hibernate mappings
not providing any instances of the Hibernate session, or state-changing dao methods.

Now the error I'd like to prevent is, someone accidentally going building.getInhabitants().clear();. I can think of these options:

Getter wrapping: Make getInhabitants first wrap inhabitants in a Collections.unmodifiableSet() call, then return it.

Pros: Least work, least extra code
Cons: Feels hacky

Wrapper classes: Rename Building to MutableBuilding, Person to MutablePerson, and provide immutable classes Building and Person. Since my application has a clear snapshot point, I can fetch the records as mutable objects (as I do now), make deeply immutable copies and present that object tree to clients.

Pros: Straight java, no Hibernate magic. I get to use my favorite keyword: final
Cons: More code to write and maintain. Also, will Hibernate keep the mutable instances in memory?

Hibernate mapping magic: Use that one magic keyword to instruct Hibernate to wrap the collections it sets on my entity objects in Collections.unmodifiableSet() or equivalent. (Note: I use an xml mapping file)

Pros: Elegant, no extra code
Cons: Such keyword may not exist

Hibernate extension: Use that one Hibernate extension point to write my own object instantiator, and in there wrap the set in Collections.unmodifiableSet() before returning it.

Pros: More elegant than hacking my getters
Cons: Such extension point may not exist

Right now I'm leaning towards #2, mostly because I don't know if 3 and 4 are possible. 
What is the best way?

A:

Option 1, for sure. It's not "hacky", and that's exactly why you abstracted the property access into methods, in the first place :-) Just note that you should use "field access" with Hibernate, instead of "method", so that you don't risk providing an unmodifiable collection to Hibernate. 
Unfortunately, Hibernate doesn't provides a way to place unmodifiable collections, but I think you can do a @PostLoad event listener to modify all collections once the object is loaded. 

