开发者

Is it a missing implementation with JPA implementation of hibernate?

开发者 https://www.devze.com 2022-12-17 08:11 出处:网络
On my way in understanding the transaction-type attribute of persistence.xml, i came across an issue / discrepency between hibernate-core and JPA-hibernate which looks weird.

On my way in understanding the transaction-type attribute of persistence.xml, i came across an issue / discrepency between hibernate-core and JPA-hibernate which looks weird.

I am not pretty sure whether it is a missing implementation with JPA of hibernate.

Let me post the comparison between the outcome of JPA implementation and the hibernate implementation of the same concept.

Environment

  1. Eclipse 3.5.1
  2. JSE v1.6.0_05
  3. Hibernate v3.2.3 [for hibernate core]
  4. Hibernate-EntityManger v3.4.0 [for JPA]
  5. MySQL DB v5.0

Issue

1.Hibernate core

package com.expt.hibernate.core;

import java.io.Serializable;

public final class Student implements Serializable {

    private int studId;

    private String studName;

    private String studEmailId;

    public Student(final String studName, final String studEmailId) {
       this.studName = studName;
       this.studEmailId = studEmailId;
    }

    public int getStudId() {
       return this.studId;
    }

    public String getStudName() {
       return this.studName;
    }

    public String getStudEmailId() {
        return this.studEmailId;
    }

    private void setStudId(int studId) {
        this.studId = studId;
    }

    private void setStudName(String studName) {
        this.studName = stuName;
    }

    private void setStudEmailId(int studEmailId) {
        this.studEmailId = studEmailId;
    }

}

2. JPA implementaion of Hibernate

package com.expt.hibernate.jpa;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "Student_Info")
public final class Student implements Serializable {

  @Id
  @GeneratedValue
  @Column(name = "STUD_ID", length = 5)
  private int studId;

  @Column(name = "STUD_NAME", nullable = false, length = 25)
  private String studName;

  @Column(name = "STUD_EMAIL", nullable = true, length = 30)
  private String studEmailId;

  public Student(final String studName, final String studEmailId) {
     this.studName = studName;
     this.studEmailId = studEmailId;
  }

  public int getStudId() {
     return this.studId;
  }

  public String getStudName() {
     return this.studName;
  }

  public String getStudEmailId() {
     return this.studEmailId;
  }

}

Also, I have provided the DB configuration properties in the associated hibernate-cfg.xml [in case of hibernate core] and persistence.xml [in case of JPA (hibernate entity manager)].

create a driver and perform

  1. add a student and

  2. query for the list of students and print their details.

Then the issue comes when you run the driver program.

Hibernate core - output

Exception in thread "main" org.hibernate.Instant开发者_开发技巧iationException: No default constructor for entity: com.expt.hibernate.core.Student at org.hibernate.tuple.PojoInstantiator.instantiate(PojoInstantiator.java:84) at org.hibernate.tuple.PojoInstantiator.instantiate(PojoInstantiator.java:100) at org.hibernate.tuple.entity.AbstractEntityTuplizer.instantiate(AbstractEntityTuplizer.java:351) at org.hibernate.persister.entity.AbstractEntityPersister.instantiate(AbstractEntityPersister.java:3604) ....

....

This exception is flashed when the driver is executed for the first time itself.

JPA Hibernate - output

First execution of the driver on a fresh DB provided the following output.

DEBUG SQL:111 - insert into student.Student_Info (STUD_EMAIL, STUD_NAME) values (?, ?) 17:38:24,229 DEBUG SQL:111 - select student0_.STUD_ID as STUD1_0_, student0_.STUD_EMAIL as STUD2_0_, student0_.STUD_NAME as STUD3_0_ from student.Student_Info student0_

student list size ==> 1

1 || Jegan || jegan.k@opensource.com

second execution of the driver provided the following output.

DEBUG SQL:111 - insert into student.Student_Info (STUD_EMAIL, STUD_NAME) values (?, ?) 17:40:25,254 DEBUG SQL:111 - select student0_.STUD_ID as STUD1_0_, student0_.STUD_EMAIL as STUD2_0_, student0_.STUD_NAME as STUD3_0_ from student.Student_Info student0_

Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.InstantiationException: No default constructor for entity: com.expt.hibernate.jpa.Student at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:614) at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:76) at driver.StudentDriver.main(StudentDriver.java:43) Caused by: org.hibernate.InstantiationException: No default constructor for entity: com.expt.hibernate.jpa.Student ....

....

Could anyone please let me know if you have encountered this sort of inconsistency?

Also, could anyone please let me know if the issue is a missing implementation with JPA-Hibernate?

~ Jegan


Well, you have a "consistent" exception:

org.hibernate.InstantiationException: No default constructor for entity: com.expt.hibernate.core.Student

Just add a default constructor on your Student entity (the JPA specification actually mandates a default constructor on mapped classes to make dynamic instantiation of the class possible by the JPA provider).

Update: (answering a comment from the OP)

yeah. i can add a default constructor and get it working but i just wanted JPA-Hibernate to tell me in the very first go not in the second run. Also, i don't really the theme behind it giving the exception during the second run and not in the first run

Honestly, I can't say why it works the first time with JPA/Hibernate and fails directly with Hibernate core (well, obviously, JPA/Hibernate didn't use dynamic instantiation on the first run but I don't know why and, actually, you skipped the interesting parts of the stacktrace :) Anyway, Hibernate and the JPA spec don't mandate exceptions to be thrown at the same time, they mandate you to provide a default constructor on your entities and you didn't. So, I wouldn't spend too much time on on this little behavioral difference as this is an implementation detail. Just build to spec and voilà! And if really you want to know, you have the source code, you have a debugger. Just use them :)


In both cases you got an error that prevented the operation, which needs the default constructor and we both know that this was the problem and what is the solution.

about the different behavior I can't answer you, you should provide more information about how you are saving the objects in both cases, maybe a session flush, or a transaction not being executed may cause the late appearance of the error using JPA!!


The class need a default constructor:

public final class Student implements Serializable {
    // ...
    public Student() {
        super();
    }
    // ...
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号