0
votes

I am planning to create one simple Spring Rest Service Project with JPA which will fetch the details from the database based on the entity name and entity id given in path variables.

consider following code.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ds.dao.EntityDAO;
import com.ds.entities.Employees;

import javax.persistence.Entity;
@Controller
@RequestMapping("/")
public class DynaRestController {

@Autowired
EntityDAO entityDAO;


@RequestMapping(value = "{entityName}/{enityId}",method = RequestMethod.GET)
public @ResponseBody Object getEntity(@PathVariable("entityName") String entityName,@PathVariable("enityId") Object id) {
    return entityDAO.getEntityById(entityName, id);
}

}

Entity DAO Class

public class EntityDAO {
@Autowired
EntityManager entityManager;


public Object getEntityById(String entityName, Object id) {
    EntityType<?> entityType = getEntityByName(entityName);
    Object idcasted = entityType.getIdType().getJavaType().cast(id);
    System.out.println(idcasted.getClass().getName());
    Object entity = entityManager.find(entityType.getJavaType(), idcasted);
    System.out.println("Entity.. Name .." + entityName);
    // Employees entity = session.load(Employees.class, id);
    return entity;

}

private EntityType<?> getEntityByName(String name) {
    Set<EntityType<?>> entities = entityManager.getMetamodel().getEntities();
    for (Iterator<EntityType<?>> iterator = entities.iterator(); iterator.hasNext();) {
        EntityType<?> entityType = (EntityType<?>) iterator.next();
        if (entityType.getName().equals(name))
            return entityType;
    }

    return null;
}

}

Employees Class

@Configurable
@Entity
@Table(name = "employees", catalog = "employees")
public class Employees implements java.io.Serializable {

/**
 * 
 */
private static final long serialVersionUID = 1L;
private int empNo;
private Date birthDate;
private String firstName;
private String lastName;
private String gender;
private Date hireDate;
private Set<Titles> titleses = new HashSet<Titles>(0);
private Set<Salaries> salarieses = new HashSet<Salaries>(0);
private Set<DeptEmp> deptEmps = new HashSet<DeptEmp>(0);
private Set<DeptManager> deptManagers = new HashSet<DeptManager>(0);

public Employees() {
}

public Employees(int empNo, Date birthDate, String firstName, String lastName, String gender, Date hireDate) {
    this.empNo = empNo;
    this.birthDate = birthDate;
    this.firstName = firstName;
    this.lastName = lastName;
    this.gender = gender;
    this.hireDate = hireDate;
}

public Employees(int empNo, Date birthDate, String firstName, String lastName, String gender, Date hireDate,
        Set<Titles> titleses, Set<Salaries> salarieses, Set<DeptEmp> deptEmps, Set<DeptManager> deptManagers) {
    this.empNo = empNo;
    this.birthDate = birthDate;
    this.firstName = firstName;
    this.lastName = lastName;
    this.gender = gender;
    this.hireDate = hireDate;
    this.titleses = titleses;
    this.salarieses = salarieses;
    this.deptEmps = deptEmps;
    this.deptManagers = deptManagers;
}

@Id
@Column(name = "emp_no", unique = true, nullable = false)
public int getEmpNo() {
    return this.empNo;
}

public void setEmpNo(int empNo) {
    this.empNo = empNo;
}

@Temporal(TemporalType.DATE)
@Column(name = "birth_date", nullable = false, length = 10)
public Date getBirthDate() {
    return this.birthDate;
}

public void setBirthDate(Date birthDate) {
    this.birthDate = birthDate;
}

@Column(name = "first_name", nullable = false, length = 14)
public String getFirstName() {
    return this.firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

@Column(name = "last_name", nullable = false, length = 16)
public String getLastName() {
    return this.lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
}

@Column(name = "gender", nullable = false, length = 2)
public String getGender() {
    return this.gender;
}

public void setGender(String gender) {
    this.gender = gender;
}

@Temporal(TemporalType.DATE)
@Column(name = "hire_date", nullable = false, length = 10)
public Date getHireDate() {
    return this.hireDate;
}

public void setHireDate(Date hireDate) {
    this.hireDate = hireDate;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "employees")
public Set<Titles> getTitleses() {
    return this.titleses;
}

public void setTitleses(Set<Titles> titleses) {
    this.titleses = titleses;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "employees")
public Set<Salaries> getSalarieses() {
    return this.salarieses;
}

public void setSalarieses(Set<Salaries> salarieses) {
    this.salarieses = salarieses;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "employees")
@JsonBackReference
public Set<DeptEmp> getDeptEmps() {
    return this.deptEmps;
}

public void setDeptEmps(Set<DeptEmp> deptEmps) {
    this.deptEmps = deptEmps;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "employees")
public Set<DeptManager> getDeptManagers() {
    return this.deptManagers;
}

public void setDeptManagers(Set<DeptManager> deptManagers) {
    this.deptManagers = deptManagers;
}

}

When i am dynamically casting the path variable by using following code

Object idcasted = entityType.getIdType().getJavaType().cast(id);
Object entity = entityManager.find(entityType.getJavaType(), idcasted);

it is throwing ClassCastExpcetion

java.lang.ClassCastException: Cannot cast java.lang.String to int at java.lang.Class.cast(Class.java:3369) ~[na:1.8.0_112] at com.techm.att.ds.dao.EntityDAO.getEntityById(EntityDAO.java:33) ~[classes/:na] at com.techm.att.ds.dao.EntityDAO$$FastClassBySpringCGLIB$$8e64d745.invoke() ~[classes/:na] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE]

any Help will be highly appriciated..

1
Id is a String and cannot be cast to an integer by the cast method. The id type of the entity is an integer. docs.oracle.com/javase/7/docs/api/java/lang/… - pL4Gu33
Yes, I know that the string cannot be typecast to Int, I am typecasting path variable that is the object type. Then why it is throwing the exception for String..? ,@PathVariable("enityId") Object id) - Anees Ahmed Mohammed
i write you a short example - pL4Gu33

1 Answers

0
votes

I write you a simple example regarding the comments. This is the same behavior. Your RestController gets actually a string:

  public static void main(String[] args) {
    Object myString = "myString";
    System.out.println(myString.getClass()); // class java.lang.String
    int.class.cast(myString);
}

The cast method checks the instanceof your given value and it fails:

 public T cast(Object obj) {
    if (obj != null && !isInstance(obj))
        throw new ClassCastException(cannotCastMsg(obj));
    return (T) obj;
}