Merhaba,
Yapmak istediğim;
Spring, Hibernate, JPA öğrenmek için küçük CRUD uygulamalar geliştirmeye çalışıyorum. Many to many anotasyon ile örnek yapmak istedim ancak takıldığım yerler için sizlerden yardım rica ederim.
Uygulamada, çalışanların sahip oldukları ehliyet sınıflarını veritabanına eklemek, güncellemek, silmek istiyorum. Kullanıcı bilgilerini sayfaya getiriyorum. Ehliyet sınıflarını (A1 sınıfı, B sınıfı vb.) veritabanından çekip CheckBoxlara Spring forEach ile getiriyorum. Kullanıcı hangi sınıftan ehliyete sahip ise ilgili CheckBox işaretlenmeli ve istediğim zaman CheckBox'ta işaretli kullanıcının sınıflarını güncelleyebilmeliyim.
Ben şu an kullanıcının sahip olduğu lisansları CheckBoxlara işaretleyebiliyorum. Yapmak istediğim şey ise; bu bilgileri güncellemektir.
Örneğin; kullanıcının A1 ve M sınıfı ehliyetleri olsun. Ekrana işaretleyerek getiriyorum.
Bunun için;
"employees", "driving_licenses" adıyla iki adet master tablo oluşturdum. Çalışanların ehliyet bilgilerini tutmak için "employee_driving_licenses" adıyla tablo oluşturdum:
employees:
id int
last_name nvarchar(20)
first_name nvarchar(10)
driving_licenses:
id int
code nvarchar(5)
employee_driving_licenses:
employee_id int
driving_license_id int
Tabloların model sınıflarını oluşturdum ve JPA anotasyonlarını ekledim. Employee ve DrivingLicense adında iki tane Entity Java classı var:
Employee.java
@Entity@Table(name = "employees")
public class Employee {
private int id;
private String last_name;
private String first_name;
private java.util.Collection<DrivingLicense> driving_licenses = new HashSet<DrivingLicense>();
@GeneratedValue(strategy = GenerationType.AUTO)
@Id
@Column
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@NotEmpty(message = "Please enter Last Name")
@Column
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
@NotEmpty(message = "Please enter First Name")
@Column
public String getFirst_name() {
return first_name;
}
@ManyToMany(fetch = FetchType.EAGER, mappedBy = "employees")
public java.util.Collection<DrivingLicense> getDriving_licenses() {
return driving_licenses;
}
public void setDriving_licenses(
java.util.Collection<DrivingLicense> driving_licenses) {this.driving_licenses = driving_licenses;
}
}
DrivingLicense.java
@Entity@Table(name = "driving_licenses")
public class DrivingLicense {
private int id;
private String code;
private java.util.Collection<Employee> employees = new HashSet<Employee>();
@Override
public int hashCode() {
return new Long(id).hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof DrivingLicense)) {
return false;
}
return this.id == ((DrivingLicense) obj).getId();
}
@GeneratedValue(strategy = GenerationType.AUTO)
@Id
@Column
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinTable(name = "employee_driving_licenses", joinColumns = { @JoinColumn(name = "driving_license_id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "employee_id", nullable = false, updatable = false) })
public java.util.Collection<Employee> getEmployees() {
return employees;
}
public void setEmployees(java.util.Collection<Employee> employees) {
this.employees = employees;
}
}
Uygulamanın DAO, Service, Controller ve View sınıflarını/sayfalarını oluşturdum.
EmployeeController.java:
@RequestMapping(value = "index", method = RequestMethod.POST)
public String employee(@Valid @ModelAttribute("employee") Employee employee,
BindingResult result, @RequestParam String action,
java.util.Map<String, Object> map) {
boolean isValid = true;
if (result.hasErrors()) {
isValid = false;
}
Employee employeeResult = new Employee();
switch (action.toLowerCase()) {
case "add":
if (isValid)
employeeService.add(employee);
employeeResult = employee;
break;
case "edit":
if (isValid)
employeeService.edit(employee);
employeeResult = employee;
break;
}
map.put("drivingLicenseList", drivingLicenseService.findActiveDrivingLicense());
map.put("employee", employeeResult);
map.put("activeEmployeeList", employeeService.findActiveEmployees());
return "employee";
}
employee.jsp:
<c:forEach var="drive_licenses" items="${drivingLicenseList}">
<form:checkbox path="driving_licenses"
value="${drive_licenses }" label="${drive_licenses.code }" />
</c:forEach>
Kullanıcının ehliyet sınıflarını değiştirip güncellediğimde aşağıdaki hatayı alıyorum:
{employee=com.ay.model.Employee@573cb29c, org.springframework.validation.BindingResult.employee=org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'employee' on field 'driving_licenses': rejected value [com.ay.model.DrivingLicense@1,com.ay.model.DrivingLicense@7,com.ay.model.DrivingLicense@8,com.ay.model.Driving License@9]; codes [typeMismatch.employee.driving_licenses,typeMismatch.driving_licenses,typeMismatch.java.util.Collection,typeMis match]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [employee.driving_licenses,driving_licenses]; arguments []; default message [driving_licenses]]; default message [Failed to convert property value of type 'java.lang.String[]' to required type 'java.util.Collection' for property 'driving_licenses'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.ay.model.DrivingLicense] for property 'driving_licenses[0]': no matching editors or conversion strategy found]}
Datayı Collection veri tipinde nasıl alabilirim? Bana birkaç yol gösterir misiniz?
Bir de employee.jsp sayfasında value="${drive_licenses }" yaptığımda doğal olarak tarayıcıda nesnenin değerini görüyorum. Aslında başlangıçta ben value="${drive_licenses.id }" yapmıştım. Ancak bu sefer de kullanıcının ehliyet belgeleri CheckBox'ta işaretlenmiyor, hepsi boş geliyordu. Model sayfasında doğru yazım şekli ne olmalı?
Şimdiden desteğiniz için teşekkürler.