I'm at a loss here and maybe this is something obvious, because my Hibernate experience is weaker than other areas.
The legacy code has a Hibernate @Entity Foo class. One of its properties is the following:
private OldBar bar = new OldBar();
OldBar is a @Embeddable class that uses a single column, foobar :
@Embeddable public class OldBar { private String fooBar; @Column(length = 10, nullable = false) private String getFooBar() { return fooBar; } @SuppressWarnings("unused") private void setFooBar(String fooBar) { this.fooBar = fooBar; } }
The initial problem was that I needed to do something with OldBar.fooBar , but the original design had limitations and had this field private, which prevented me from subclassing it, so I had to create a whole class, NewBar , replace another and gain access to the private field. I thought that since NewBar also Embeddable and has the same @Column notation, I could just swap the field in the Foo class:
private NewBar bar = new NewBar();
I wanted to do this because I have existing data in the foobar column, and I wanted to transparently use this data with NewBar instead of OldBar .
Through the trace logs, I saw that Foo() is created with its default version of NewBar() , as you would expect when the constructor is called. However, according to the time code, calling Foo.getBar() , for some reason, bar is null ! I assume that Hibernate is null for some reason, but why doesn't Hibernate read data from the foobar column and create an instance of NewBar ? Why does it work again when I put an OldBar instead of a NewBar ? Is there really nothing said in the database itself about which of the @Embeddable classes @Embeddable mapped to a column, is there?
Update: it is becoming strange and unfamiliar. Sometimes I will give the code for the night, and the next day it works! Or the next day it won’t work! Now this did not work (i.e., the foobar property was set to null instead of the value in the database), so I made the ExactCopyOfOldBar class and placed it instead of OldBar . Everything went perfectly! Therefore, I return to NewBar , simply NewBar my temporary changes. It still worked when it wasn’t before! Is there some kind of cache where Hibernate serializes the values and doesn't get them from the database? It is very strange.
Update: Now I can no longer run NewBar . I create OtherBar , which is basically identical to NewBar , except that it has a different name, and I plug it in and it works by reading the inline correctly. I switch back to NewBar and I get null again. What's happening?
Note that Foo loaded via net.databinder.auth.hib.AuthDataApplication.getUser(String username) , which is quite simple:
return (DataUser) Databinder.getHibernateSession().createCriteria(getUserClass()) .add(Restrictions.eq("username", username)).uniqueResult();
I checked again and again that the Foo (user) table has one row with the correct data, and most importantly, the foobar field contains the data. Why does Hibernate return me a Foo with a null foobar field? Why NewBar just switching from NewBar to OtherBar make it work again? Why does it work all day and then stops working after I left it for the night?