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?