Я новичок в Spring MVC. В моем небольшом проекте crm я хочу отобразить объектный список с вложенным объектом. Но он показывает только объект внутри имени объекта, например de.fischerlandmaschinen.crm.model.Employee@6018ebcc statt преобразованной строки имени.
ниже приведены коды:
Домен:
@Entity
@Table(name = "CUSTOMER")
public class Customer implements Serializable {
private static final long serialVersionUID = 5015685214532097319L;
private Long id;
private String foreignId;
private String title;
private String firstName;
private String middleName;
@NotEmpty
private String lastName;
@Enumerated(EnumType.STRING)
private Gender gender;
@Past
@Temporal(TemporalType.DATE)
private Date dateOfBirth;
@Valid
private Address address = new Address();
@Valid
private Contact contact = new Contact();
private Company company = null; // new Company();
private String notice;
@Past
@Temporal(TemporalType.DATE)
private Date createdDate;
@Past
@Version
@Temporal(TemporalType.DATE)
private Date lastUpdatedDate;
private String status;
private Employee primaryConsultant = null; //new Employee();
private Employee secondaryConsultant = null; //new Employee();
public Customer(){
createdDate = new Date();
lastUpdatedDate = new Date();
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "customer_id")
public Long getId() {
return id;
}
public void setId(Long customerId) {
this.id = customerId;
}
@Column(name = "foreign_id")
public String getForeignId() {
return foreignId;
}
public void setForeignId(String foreignId) {
this.foreignId = foreignId;
}
@OneToOne(cascade = CascadeType.ALL)
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@OneToOne(cascade = CascadeType.ALL)
public Contact getContact() {
return contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
@Column(name = "created_date")
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
@Column(name = "date_of_birth")
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
@ManyToOne(fetch=FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
@JoinColumn(name="company", nullable=true)
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
public String getNotice() {
return notice;
}
public void setNotice(String notice) {
this.notice = notice;
}
@Column(name = "last_updated_date")
public Date getLastUpdatedDate() {
return lastUpdatedDate;
}
public void setLastUpdatedDate(Date lastUpdatedDate) {
this.lastUpdatedDate = lastUpdatedDate;
}
// @ManyToOne(fetch=FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="primary_consultant", nullable=true)
public Employee getPrimaryConsultant() {
return primaryConsultant;
}
public void setPrimaryConsultant(Employee primaryConsultant) {
this.primaryConsultant = primaryConsultant;
}
// @ManyToOne(fetch=FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="secondary_consultant", nullable=true)
public Employee getSecondaryConsultant() {
return secondaryConsultant;
}
public void setSecondaryConsultant(Employee secondaryConsultant) {
this.secondaryConsultant = secondaryConsultant;
}
}
и домен сотрудника:
@Entity
@Table(name = "EMPLOYEE")
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String alias;
private String title;
private String firstName;
private String middleName;
private String lastName;
// getter and setter
}
В моем контроллере:
@RequestMapping(value = "customer/list")
public ModelAndView list() {
ModelAndView mav = new ModelAndView("customer/list");
List<Customer> customers = customerService.getAllCustomers();
mav.addObject("customerList", customers);
return mav;
}
@InitBinder
protected void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");
dateFormat.setLenient(false);
binder.setAutoGrowNestedPaths(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(
dateFormat, true));
binder.registerCustomEditor(Gender.class, new GenderEditor());
binder.registerCustomEditor(Employee.class,
new CustomEmployeePropertyEditor(employeeService));
}
И у меня CustomEmployeePropertyEditor расширяет PropertyEditorSupport для initBinder:
@Override
public void setAsText(String text) {
logger.info("convert string to employee object");
if (text == null || text.length() == 0) {
setValue(null);
return;
}
Long id = (Long) typeConverter.convertIfNecessary(text, Long.class);
if (id == null) {
setValue(null);
return;
}
setValue(employeeService.getEmployee(id));
}
@Override
public String getAsText() {
logger.info("convert employee object to string");
Object obj = getValue();
if (obj == null) {
return null;
}
return (String) typeConverter.convertIfNecessary(
((Employee) obj).getLastName(), String.class);
}
@Override
public void setAsText(String text) {
logger.info("convert string to employee object");
if (text == null || text.length() == 0) {
setValue(null);
return;
}
Long id = (Long) typeConverter.convertIfNecessary(text, Long.class);
if (id == null) {
setValue(null);
return;
}
setValue(employeeService.getEmployee(id));
}
@Override
public String getAsText() {
logger.info("convert employee object to string");
Object obj = getValue();
if (obj == null) {
return null;
}
return (String) typeConverter.convertIfNecessary(
((Employee) obj).getLastName(), String.class);
}
И умереть JSP код:
<c:forEach items="${customerList}" var="customer">
<tr>
<td>${customer.id}</td>
...
<td>${customer.primaryConsultant}</td>
<td>${customer.secondaryConsultant}</td>
...
</tr>
</c:forEach>
Но я получаю нежелательный результат в браузере:
de.fischerlandmaschinen.crm.model.Employee@6018ebcc
в полях primaryConsultant и secondConsultant
Что не так. И я ищу документ registerCustomEditor. он говорит, что это может для свойства вложенного пути тоже. Что означает свойство пути? Путь на странице .jsp или свойство в доменном объекте?
спасибо
Людвиг