I've created an entity called Person. It implements Lifecycle interface. The onLoad method sets the department property. Sometimes a department is unknown (== null).
@Entity
@Table(name = "PERSON")
public class Person implements Lifecycle {
@Column(name = "NAME", length = 128, columnDefinition = "VARCHAR2(128)")
String name;
@Transient
Department department;
public void onLoad(Session s, Serializable id) {
// some logic resolving department
}
}
Is there any way to make the department property a virtual column (or something like this) - never created in the database.
@Entity
@Table(name = "PERSON")
public class Person {
@Column(name = "NAME", length = 128, columnDefinition = "VARCHAR2(128)")
String name;
@Type(type = "DepartmentType") // UserType for resolving a department
//@Transcient
//@Column(insertable = false, updatable = false)
//@NotFound(action = NotFoundAction.IGNORE)
// ... don't have a clue
Department department;
}
I would like to have the ability to use Criteria.
Criteria criteria = session.createCriteria(Person.class);
criteria.add(Restrictions.isNotNull("department"));
List<Person> list = criteria.list();
I understand that Criteria executes before finding the department, so the property 'department' could not be resolved.
I've seen that I can remove a row from UserType's nullSafeGet
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
rs.deleteRow();
}
but I don't want to delete the row from database (it's read-only!).
To sum up my questions are:
1) Is it possible to create a virtual column?
2) Is there any more efficient way of doing this?
Criteria criteria = session.createCriteria(Person.class);
// ... some restrictions ...
List<Person> list = criteria.list();
Iterator<EbamLogMessageEntity> it = list.iterator();
while(it.hasNext()) {
Person p = it.next();
Department d = resolveDepartment(p)
if(d == null) {
it.remove();
} else {
p.setDepartment(d);
}
}
It's possible, if you can express the content of the virtual column as a SQL formula, using the
@Formula
annotation. See the documentation for more details. If the virtual column is a virtual join column, you may also use the@JoinFormula
annotation.