Maintenant, j'apprends l'hibernation et je commence à l'utiliser dans mon projet. C'est une application CRUD. J'ai utilisé hibernate pour toutes les opérations crud. Cela fonctionne pour tous. Mais, un-à-plusieurs et plusieurs-à-un, je suis fatigué d'essayer. Enfin, il me donne l'erreur ci-dessous.
org.hibernate.MappingException: Could not determine type for: Java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)]
Là encore, je suis passé par ce tutoriel vidéo . C'est très simple pour moi, au début. Mais je ne peux pas le faire fonctionner. C'est aussi maintenant, dit
org.hibernate.MappingException: Could not determine type for: Java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)]
J'ai effectué des recherches sur Internet, quelqu'un a dit c'est un bogue dans Hibernate , et certains disent, en ajoutant @GenereatedValue cette erreur sera supprimée. Mais rien ne fonctionne pour moi,
J'espère que je vais obtenir un correctif!
Merci!
Voici mon code:
College.Java
@Entity
public class College {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int collegeId;
private String collegeName;
private List<Student> students;
@OneToMany(targetEntity=Student.class, mappedBy="college", fetch=FetchType.EAGER)
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}//Other gettters & setters omitted
Student.Java
@Entity
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int studentId;
private String studentName;
private College college;
@ManyToOne
@JoinColumn(name="collegeId")
public College getCollege() {
return college;
}
public void setCollege(College college) {
this.college = college;
}//Other gettters & setters omitted
Main.Java:
public class Main {
private static org.hibernate.SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
initSessionFactory();
}
return sessionFactory;
}
private static synchronized void initSessionFactory() {
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
}
public static Session getSession() {
return getSessionFactory().openSession();
}
public static void main (String[] args) {
Session session = getSession();
Transaction transaction = session.beginTransaction();
College college = new College();
college.setCollegeName("Dr.MCET");
Student student1 = new Student();
student1.setStudentName("Peter");
Student student2 = new Student();
student2.setStudentName("John");
student1.setCollege(college);
student2.setCollege(college);
session.save(student1);
session.save(student2);
transaction.commit();
}
}
Console:
Exception in thread "main" org.hibernate.MappingException: Could not determine type for: Java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.Java:306)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.Java:290)
at org.hibernate.mapping.Property.isValid(Property.Java:217)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.Java:463)
at org.hibernate.mapping.RootClass.validate(RootClass.Java:235)
at org.hibernate.cfg.Configuration.validate(Configuration.Java:1330)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.Java:1833)
at test.hibernate.Main.initSessionFactory(Main.Java:22)
at test.hibernate.Main.getSessionFactory(Main.Java:16)
at test.hibernate.Main.getSession(Main.Java:27)
at test.hibernate.Main.main(Main.Java:43)
Le XML:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/dummy</property>
<property name="connection.username">root</property>
<property name="connection.password">1234</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping class="test.hibernate.Student" />
<mapping class="test.hibernate.College" />
</session-factory>
Vous utilisez stratégie d'accès au champ (déterminé par l'annotation @Id). Placez toute annotation liée à JPA juste au-dessus de chaque champ au lieu de la propriété getter
@OneToMany(targetEntity=Student.class, mappedBy="college", fetch=FetchType.EAGER)
private List<Student> students;
L'ajout du @ElementCollection
au champ Liste a résolu ce problème:
@Column
@ElementCollection(targetClass=Integer.class)
private List<Integer> countries;
Problème avec stratégies d'accès
En tant que fournisseur JPA, Hibernate peut procéder à une introspection des deux attributs d'entité (champs d'instance) ou les accesseurs (propriétés d'instance). Par défaut, l'emplacement de l'annotation
@Id
donne l'accès par défaut stratégie. Lorsqu'il est placé sur un champ, Hibernate suppose que accès. Placé sur l'identifiant getter, Hibernate utilisera accès basé sur la propriété.
Accès basé sur le champ
Lorsque vous utilisez un accès basé sur le champ, l’ajout d’autres méthodes au niveau de l’entité est beaucoup plus flexible car Hibernate ne tient pas compte de celles qui font partie de l’état de persistance.
@Entity
public class Simple {
@Id
private Integer id;
@OneToMany(targetEntity=Student.class, mappedBy="college",
fetch=FetchType.EAGER)
private List<Student> students;
//getter +setter
}
Accès basé sur les propriétés
Lors de l'utilisation de l'accès basé sur la propriété, Hibernate utilise les accesseurs pour lire et écrire l'état de l'entité.
@Entity
public class Simple {
private Integer id;
private List<Student> students;
@Id
public Integer getId() {
return id;
}
public void setId( Integer id ) {
this.id = id;
}
@OneToMany(targetEntity=Student.class, mappedBy="college",
fetch=FetchType.EAGER)
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
}
Mais vous ne pouvez pas utiliser à la fois les accès basés sur les champs et ceux basés sur les propriétés. Il montrera comme cette erreur pour vous
Pour plus d'idées suivez this
@Access(AccessType.PROPERTY)
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name="userId")
public User getUser() {
return user;
}
J'ai les mêmes problèmes, je l'ai résolu en ajoutant @Access(AccessType.PROPERTY)
Bien que je sois nouveau pour hiberner mais avec peu de recherche (essais et erreurs on peut dire) J'ai découvert que cela est dû à une incohérence dans l’annotation des méthodes/fileds.
lorsque vous annotez @ID sur une variable, assurez-vous que toutes les autres annotations sont également effectuées sur la variable uniquement et lorsque vous annotez-le sur la méthode getter, assurez-vous que vous annotez uniquement toutes les autres méthodes getter et non leurs variables respectives.
Ne t'inquiète pas! Ce problème est dû à l'annotation. Au lieu d'un accès basé sur le champ, l'accès basé sur les propriétés résout ce problème. Le code comme suit:
package onetomanymapping;
import Java.util.List;
import javax.persistence.*;
@Entity
public class College {
private int collegeId;
private String collegeName;
private List<Student> students;
@OneToMany(targetEntity = Student.class, mappedBy = "college",
cascade = CascadeType.ALL, fetch = FetchType.EAGER)
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Id
@GeneratedValue
public int getCollegeId() {
return collegeId;
}
public void setCollegeId(int collegeId) {
this.collegeId = collegeId;
}
public String getCollegeName() {
return collegeName;
}
public void setCollegeName(String collegeName) {
this.collegeName = collegeName;
}
}