When using PropertyEditors with Spring MVC is it bad to have them fetch entities from the database? Should I instead create an empty entity and set its Id.
For instance for the entity Employee:
@Entity
@Table(name = "employee")
public class Employee implements GenericEntity<Integer>{
    @Id
    @GeneratedValue
    @Column(name = "employee_id")
    public Integer getEmployeeId() {
        return employeeId;
    }
    public void setEmployeeId(Integer employeeId) {
        this.employeeId = employeeId;
    }
    /** More properties here **/
}
Is it a bad idea to fetch the Entity in the PropertyEditor below with the following GenericEntityEditor:
public class GenericEntityEditor<ENTITY extends GenericEntity<Integer>> extends PropertyEditorSupport {
    private GenericDao<ENTITY, Integer> genericDao;
    public GenericEntityEditor(GenericDao<ENTITY, Integer> genericDao) {
        this.genericDao = genericDao;
    }
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        setValue(genericDao.findById(Integer.valueOf(text)));
    }
    @SuppressWarnings("unchecked")
    @Override
    public String getAsText() {
        ENTITY entity = (ENTITY) getValue();
        if(entity == null) {
            return null;
        } 
        return String.valueOf(entity.getId());
    }
}
Which can be bound in the controller:
@Controller
public class EmployeeController {
    /** Some Service-layer resources **/
    @Resource
    private EmployeeDao employeeDao; // implements GenericDao<ENTITY, Integer> genericDao
    @SuppressWarnings("unchecked")
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Employee.class, new GenericEntityEditor(employeeDao));
    }
    /** Some request mapped methods **/
}
Is it preferred to use a more specific approach with a EmployeeEditor and have it just instantiate an Employee entity and set its id:
public class EmployeeEditor extends PropertyEditorSupport {
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        Employee employee = new Employee();
        employee.setId(Integer.valueOf(text));
    }
    @SuppressWarnings("unchecked")
    @Override
    public String getAsText() {
        Employee employee = (Employee) getValue();
        if(employee == null) {
            return null;
        } 
        return String.valueOf(employee.getId());
    }
}
This way we do not do a roundtrip to the DB each time an Employee exists on a Form, but I'm unsure if this works as expected with Hibernate?
I think it is legal. I used this technice for some time, and it worked well.
But Spring 3.0 has a better concept. So called Converter (Reference Chapter 5.5 Spring 3 Type Conversion)
This converters work like one way property editors. But they are Stateless, and because of this more performat, and can be reuesed!
Added: There is an not (yet) documented feature of Spring 3.0.>3: the org.springframework.core.convert.support.IdToEntityConverter
It is automatically registered in the ConversationService by the ConcersationServiceFactory.
This IdToEntityConverter will automatically convert everything (Object) to an Entity, if the entity!! has a static method find<entityName> which has one parameter and the return type is of type of the entity.
/**
 * Converts an entity identifier to a entity reference by calling a static finder method
 * on the target entity type.
 *
 * <p>For this converter to match, the finder method must be public, static, have the signature
 * <code>find[EntityName]([IdType])</code>, and return an instance of the desired entity type.
 *
 * @author Keith Donald
 * @since 3.0
 */
If you have doubt how to implement such a static finder method in your entity. Then have a look at Spring Roo generated entities.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With