Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

org.hibernate.PropertyNotFoundException: Could not find setter for 0

I'm fetching only selected attributes from a table using HQL, maintaining a list of non-entity class objects. For Eg. My entity class:

@Entity
@Table(name="STUDENT")
public class Student {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @Column(name="NAME", columnDefinition="TEXT", length="60", nullable = false)
    private String name;

    @ManyToOne
    @JoinColumn(name = "Dept_id", nullable = false)
    private Department department;

    // Other fields...
    // Getter-Setters
}

and non-persistent DTO class is having only fewer class members (say, name only):

public class StudentDTO {
    private String name;
    // Getter-Setter for name
}

Now using

public List<StudentDTO> getStudents(Long deptId) {
    List<StudentDTO> students;

    Query query = session.createQuery("select student.name " +
            "from Student as student " +
            "where Dept_id =?").setResultTransformer(new AliasToBeanResultTransformer(StudentDTO.class));
    query.setString(0, Long.toString(deptId));

    students = CommonUtil.castList(StudentDTO.class, query.list()); 
    return students;
}

where castList converts any collection into ArrayList.

public static <T> List<T> castList(Class<? extends T> clazz, Collection<?> c) {
            List<T> resultList = new ArrayList<T>(c.size());
            for(Object o: c)
              resultList.add(clazz.cast(o));
            return resultList;
        }

throws org.hibernate.PropertyNotFoundException: Could not find setter for 0 on class ../StudentDTO

Referring Hibernate exception PropertyNotFoundException when using Transformer, I changed my query to "select student.id as id,...", having Long id inside StudentDTO but that throw same exception, saying setter not found for 1.

Getter/Setters are given for each property. Please suggest changes!

like image 526
masT Avatar asked Sep 11 '13 14:09

masT


3 Answers

As you are using AliasToBeanResultTransformer, you have to declare proper alias names in your query. The class name itself says that it will transform the results into your resultClass using the alias names.

The transformTuple method of AliasToBeanResultTransformer class uses the alias names to find the setter methods of your resultClass (StudentDto):

for (int i = 0; i < aliases.length; i++) {
                    String alias = aliases[i];
                    if(alias != null) {
                        setters[i] = propertyAccessor.getSetter(resultClass, alias);
                    }
                }

In order to make AliasToBeanResultTransformer work properly you need to use proper alias names in your query. If the property name in your StudentDto class is name, you should use select student.name as name. Using select student.name as n will again throw exception. The alias names that you are using in the query should be same as the property names in your DTO class.

like image 86
Debojit Saikia Avatar answered Oct 04 '22 04:10

Debojit Saikia


just write each column name as below : Select column_name as property_name , ...., from Class_name

eg: select student.name as name from Student

like image 38
jaskirat Singh Avatar answered Oct 02 '22 04:10

jaskirat Singh


set alias for each field in select clause, these field is same as filed name in your persistence class which you set as transformer class in your query, for example:

 public mypersistenceclass()
    {
    // define constructor
    public mypersistenceclass(){}

       private String username;
    // define setter and getter

 }

  public userclass()
  {
  ...
     Query query = session.createQuery("select Users.username as username ...")
      .setResultTransformer(new AliasToBeanResultTransformer(mypersistenceclass.class));

  ...
  }
like image 35
M2E67 Avatar answered Oct 05 '22 04:10

M2E67