views:

145

answers:

3

Consider the following code:

@Entity
@Table(name = "a")
public class A implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    public int id;

    @Transient
    public B b;

    public B getB()
    {
     return B;
    }
}

When I fetch A, I'm manually filling B (another hibernate entity). If I try and access by by using a.b, then it fails, but, if I user a.getB(); then it succeeds.

Why is this?

+1  A: 

Sounds like a lazy fetching issue. The public reference is null when you try to access it directly, but when you do it with "get", Hibernate knows to call out to the database and hydrate that instance for you.

duffymo
That's what it sounded like to me, too, except that I can call a.getB(), then call a.b, and a.b still fails.
Jesse
+1  A: 
  1. Class members should ever be private!
  2. If your object is attached to the Hibernate Session, you're working on a proxy. So, if you like to access your class member directly (which is bad!), you have to detach the object first.
oeogijjowefi
I'm assuming you meant that class members should always be private, and yes, I agree, but I inherited this code and would have to change thousands of references in JSPs, so that is unlikely to happen.
Jesse
Okay, I hope the messed up architecture is not your fault, then ;). But have you tried to detach the object? I suppose, based on such an architecture, the OpenSessionInViewFilter (or (anti-)"pattern")) is used, so the object won't be detached within the request.You have to keep in mind, that the actual object is a proxy and access to members and methods relies on the persistence manager's strategy or implementation. And Hibernate assumes that some rules are followed, like not to access members directly.
oeogijjowefi
I'm actually trying to fix the architecture.I tried evicting the object after it was retrieved, but all that got me was the following exception after I tried to access anything: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
Jesse
I ended up making everything private, and spending three days sifting through JSPs, but it eventually solved my problem.
Jesse
A: 

Because b field is transient.

Is there any need for it to be transient? Try removing it.

Tom
The only need for it to be transient is that I don't want that link in the database.
Jesse