Quote:
Das Zauberwort ist hierbei: das initialisierte. Der Folder-Proxy ist aber nicht initialisiert. Kannst du Beispiel-Code einer Entity posten, bei dem es funktioniert?
Genau auf den Punkt wollte ich hinaus: Das Objekt ist tatsächlich initialisiert, obwohl es auf die gleiche Art geladen wird. Natürlich mit dem Unterschied, dass es nicht einer Vererbungshierarchie unterworfen ist.
Für mich macht das auch weitgehend Sinn: Ohne Vererbung handelt es sich bei meinem Pojo um ein einfache Sammlung (nicht referentieller) Datenobjekte. Bei der Vererbung kommt plötzlich das Zusammenspiel referenzierender Objekte zusammen (Meta und Subklasse), als gibt es einen Ansatz für Lazy-Loading.
Ein funktionierendes Beispiel, diesmal etwas ausführlicher mit DAO-Code:
Die generische DAO Klasse, leicht modifiziert zum Original und gekürzt:
Code:
public abstract class GenericHibernateDAO<T, ID extends Serializable> implements GenericDAO<T, ID>
{
private Class<T> persistentClass;
private Session session;
@SuppressWarnings("unchecked")
public GenericHibernateDAO()
{
persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public GenericHibernateDAO(Session session)
{
this();
setSession(session);
}
public void setSession(Session session)
{
this.session = session;
}
protected Session getSession()
{
if (session == null)
{
// TODO
// session = HibernateUtil.getSessionFactory().getCurrentSession();
throw new IllegalStateException("The hibernate session is not initialized.");
}
return session;
}
@SuppressWarnings("unchecked")
public T findById(ID id)
{
return (T) getSession().load(getPersistenceClass(), id);
}
}
Eine konkrete Ableitung des DAOs
Code:
public class TokenHibernateDAO extends
GenericHibernateDAO<Token, Long> implements TokenDAO
{
// void
}
Das Token Model:
Code:
@Entity
@Table(name = "tokens")
public class Token
{
@Id
@GeneratedValue
private long userId;
@Column(nullable = false)
private String token = "";
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((token == null) ? 0 : token.hashCode());
result = prime * result + (int) (userId ^ (userId >>> 32));
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Token))
return false;
Token other = (Token) obj;
if (token == null)
{
if (other.token != null)
return false;
}
else if (!token.equals(other.token))
return false;
if (userId != other.userId)
return false;
return true;
}
public long getUserId()
{
return userId;
}
public void setUserId(long userId)
{
this.userId = userId;
}
public String getToken()
{
return token;
}
public void setToken(String token)
{
this.token = token;
}
}
Eine Controller-Methode, welche das DAO nutzt:
Code:
public Token getEntry(long id)
{
Session session = null;
Transaction tk = null;
Token result = null;
try
{
session = sessionFactory.openSession();
tk = session.beginTransaction();
TokenHibernateDAO dao = createTokenDao(session);
result = (Token)dao.findById(Long.valueOf(id));
tk.commit();
return result;
}
catch(HibernateException e)
{
if(tk != null)
{
try
{
tk.rollback();
}
catch(Throwable t)
{
// log
}
}
// throw exception
}
finally
{
if(session != null)
{
try
{
session.close();
}
catch(Throwable t)
{
// log
}
}
}
}
Nun wird diese Controller-Methode bsp. in einem UnitTest verwendet:
Code:
public void testGetEntry()
{
Token token = controller.getEntry(id);
assertEquals(token.getId(), id); // keine Exception, funktioniert!
}