Questions JPA/Hibernate
Fermé
Nathalie099
Messages postés
11
Date d'inscription
mardi 30 avril 2019
Statut
Membre
Dernière intervention
28 novembre 2024
-
Modifié le 11 nov. 2020 à 16:45
Nathalie099 Messages postés 11 Date d'inscription mardi 30 avril 2019 Statut Membre Dernière intervention 28 novembre 2024 - 12 nov. 2020 à 09:00
Nathalie099 Messages postés 11 Date d'inscription mardi 30 avril 2019 Statut Membre Dernière intervention 28 novembre 2024 - 12 nov. 2020 à 09:00
3 réponses
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 019
10 nov. 2020 à 17:03
10 nov. 2020 à 17:03
Bonjour,
Tout d'abord enlève les valeurs par défaut sur tes attributs.
Par exemple :
Si la valeur est 0, ce qui est le cas par défaut dans ton code, alors Hibernate va l'enregistrer explicitement avec la valeur 0, et ce pour toutes les entités.
La génération automatique de la valeur ne sera faite que si la valeur est null (par défaut).
Il vaut donc mieux mettre :
Et pareil pour tous les autres attributs.
Ensuite je te conseilles d'enlever les constructeurs de l'entité, de ne laisser que le constructeur vide (par défaut) et d'utiliser les setters uniquement pour remplir les valeurs.
Plus embêtant, tu as déclaré
Il faudrait plutôt utiliser le DiscriminatorType.STRING pour correspondre à ton nchar(10)
Tout d'abord enlève les valeurs par défaut sur tes attributs.
Par exemple :
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer idArticle = 0;
Si la valeur est 0, ce qui est le cas par défaut dans ton code, alors Hibernate va l'enregistrer explicitement avec la valeur 0, et ce pour toutes les entités.
La génération automatique de la valeur ne sera faite que si la valeur est null (par défaut).
Il vaut donc mieux mettre :
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer idArticle;
Et pareil pour tous les autres attributs.
Ensuite je te conseilles d'enlever les constructeurs de l'entité, de ne laisser que le constructeur vide (par défaut) et d'utiliser les setters uniquement pour remplir les valeurs.
Plus embêtant, tu as déclaré
@DiscriminatorColumn( name="discriminator", discriminatorType = DiscriminatorType.INTEGER)et précisé
@DiscriminatorValue("Ramette")et
@DiscriminatorValue("Stylo"), tu as donc un conflit Integer vs String.
Il faudrait plutôt utiliser le DiscriminatorType.STRING pour correspondre à ton nchar(10)
Nathalie099
Messages postés
11
Date d'inscription
mardi 30 avril 2019
Statut
Membre
Dernière intervention
28 novembre 2024
Modifié le 11 nov. 2020 à 16:48
Modifié le 11 nov. 2020 à 16:48
Merci beaucoup. Voici mes classes actualisées pour y voir plus clair et les erreurs retournées :
package fr.eni.hibernate.entities; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.DiscriminatorColumn; import javax.persistence.DiscriminatorType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Table; @Entity @Table(name = "Articles", schema="PAPETERIE_TEST") @Inheritance( strategy = InheritanceType.SINGLE_TABLE ) @DiscriminatorColumn( name="discriminator", discriminatorType = DiscriminatorType.STRING) public abstract class Articles implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer idArticle; @Column(name = "reference") private String reference; @Column(name = "marque") private String marque ; @Column(name = "designation") private String designation; @Column(name = "prixUnitaire") private float prixUnitaire ; @Column(name = "qteStock") private int qteStock ; public Articles(){ } public Integer getIdArticle(){ return idArticle; } public String getReference(){ return reference; } public void setReference(String reference) { this.reference = reference; } public String getMarque(){ return marque; } public void setMarque(String marque) { this.marque = marque; } public String getDesignation(){ return designation; } public void setDesignation(String designation) { this.designation = designation; } public float getPrixUnitaire(){ return prixUnitaire; } public void setPrixUnitaire(float prixUnitaire) { this.prixUnitaire = prixUnitaire; } public int getQteStock(){ return qteStock; } public void setQteStock(int qteStock) { this.qteStock = qteStock; } @Override public String toString(){ return "Article [idArticle=" + idArticle + ", reference=" + reference + ", marque=" + marque + ", designation=" + designation + ", prixUnitaire=" + prixUnitaire + ", qteStock=" + qteStock + "]"; } }
package fr.eni.hibernate.entities; import javax.persistence.Column; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; @Entity @DiscriminatorValue("Stylo") public class Stylo extends Articles { private static final long serialVersionUID = 1L; private String couleur; public Stylo(){ } @Column(name = "couleur") public String getCouleur(){ return couleur; } public void setCouleur(String couleur) { this.couleur = couleur; } @Override public String toString(){ return super.toString() + " Stylo [couleur=" + couleur + "]"; } }
package fr.eni.hibernate.entities; import javax.persistence.Column; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; @Entity @DiscriminatorValue("Ramette") public class Ramette extends Articles { private static final long serialVersionUID = 1L; private int grammage; public Ramette(){ } @Column(name = "grammage") public int getGrammage(){ return grammage; } public void setGrammage(int grammage) { this.grammage = grammage; } @Override public String toString(){ return super.toString() + " Ramette [grammage=" + grammage + "]"; } }
package fr.eni.hibernate.entities; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.persistence.TypedQuery; public class Main { public static void main(String[] args) throws Exception { EntityManagerFactory entityManagerFactory = null; EntityManager entityManager = null; try { entityManagerFactory = Persistence.createEntityManagerFactory("WebStore"); entityManager = entityManagerFactory.createEntityManager(); TypedQuery<Articles> query = entityManager.createQuery("from Articles", Articles.class); List<Articles> art = query.getResultList(); for (Articles article : art) { System.out.println(art.getClass().getName()); System.out.println("\t" + article); } } finally { if (entityManager != null) entityManager.close(); if (entityManagerFactory != null) entityManagerFactory.close(); } } }
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence https://www.oracle.com/java/technologies/ version="2.0"> <persistence-unit name="WebStore"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <class>fr.eni.hibernate.entities.Articles</class> <class>fr.eni.hibernate.entities.Ramette</class> <class>fr.eni.hibernate.entities.Stylo</class> <properties> <property name="javax.persistence.jdbc.driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" /> <property name="javax.persistence.jdbc.url" value="jdbc:sqlserver://localhost;database=PAPETERIE_TEST" /> <property name="javax.persistence.jdbc.user" value="**" /> <property name="javax.persistence.jdbc.password" value="**" /> <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect" /> <property name="hibernate.format_sql" value="false" /> </properties> </persistence-unit> </persistence>
nov. 11, 2020 2:55:35 PM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation INFO: HHH000204: Processing PersistenceUnitInfo [name: WebStore] nov. 11, 2020 2:55:35 PM org.hibernate.Version logVersion INFO: HHH000412: Hibernate ORM core version 5.4.23.Final nov. 11, 2020 2:55:35 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit> INFO: HCANN000001: Hibernate Commons Annotations {5.1.2.Final} nov. 11, 2020 2:55:35 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!) nov. 11, 2020 2:55:35 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH10001005: using driver [com.microsoft.sqlserver.jdbc.SQLServerDriver] at URL [jdbc:sqlserver://localhost;database=PAPETERIE_TEST] nov. 11, 2020 2:55:35 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH10001001: Connection properties: {password=****, user=sa} nov. 11, 2020 2:55:35 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH10001003: Autocommit mode: false nov. 11, 2020 2:55:35 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections <init> INFO: HHH000115: Hibernate connection pool size: 20 (min=1) nov. 11, 2020 2:55:36 PM org.hibernate.dialect.Dialect <init> INFO: HHH000400: Using dialect: org.hibernate.dialect.SQLServerDialect nov. 11, 2020 2:55:36 PM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] nov. 11, 2020 2:55:36 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions WARN: SQL Error: 208, SQLState: S0002 nov. 11, 2020 2:55:36 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions ERROR: Nom d'objet 'PAPETERIE_TEST.Articles' non valide. nov. 11, 2020 2:55:36 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PoolState stop INFO: HHH10001008: Cleaning up connection pool [jdbc:sqlserver://localhost;database=PAPETERIE_TEST] Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154) at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1542) at org.hibernate.query.Query.getResultList(Query.java:165) at fr.eni.hibernate.entities.Main.main(Main.java:21) Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:103) at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:67) at org.hibernate.loader.Loader.getResultSet(Loader.java:2304) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2057) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2019) at org.hibernate.loader.Loader.doQuery(Loader.java:948) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349) at org.hibernate.loader.Loader.doList(Loader.java:2850) at org.hibernate.loader.Loader.doList(Loader.java:2832) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2664) at org.hibernate.loader.Loader.list(Loader.java:2659) at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:506) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:400) at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1414) at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1565) at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1533) ... 2 more Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Nom d'objet 'PAPETERIE_TEST.Articles' non valide. at mssql.jdbc@8.4.1.jre8/com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:262) at mssql.jdbc@8.4.1.jre8/com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1632) at mssql.jdbc@8.4.1.jre8/com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:602) at mssql.jdbc@8.4.1.jre8/com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:524) at mssql.jdbc@8.4.1.jre8/com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7375) at mssql.jdbc@8.4.1.jre8/com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:3206) at mssql.jdbc@8.4.1.jre8/com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:247) at mssql.jdbc@8.4.1.jre8/com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:222) at mssql.jdbc@8.4.1.jre8/com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:446) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:57) ... 17 more
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 019
11 nov. 2020 à 17:31
11 nov. 2020 à 17:31
Essayes de retirer
De mon côté, j'ai essayé de tester ton code (avec une autre architecture donc il y a des différences), et il apparaît d'autres erreurs, qu'il faudrait que tu corriges aussi :
schema="PAPETERIE_TEST"pour voir si tu as la même erreur ou non.
De mon côté, j'ai essayé de tester ton code (avec une autre architecture donc il y a des différences), et il apparaît d'autres erreurs, qu'il faudrait que tu corriges aussi :
- Il te manque l'annotation @Column(name = "idarticle")
- Il ne faut pas mettre de majuscules dans @Column(name) sinon Hibernate essaye de mettres des _ avant les majuscules. Par exemple @Column(name = "idArticle") va chercher id_article au lieu de idarticle. Une alternative serait de renommer les noms de colonnes dans la base pour avoir des _
- Tu as écrit @DiscriminatorColumn(name="discriminator") mais la colonne discriminator n'existe pas, vu ta table je pense qu'il faudrait mettre @DiscriminatorColumn(name="type")
Nathalie099
Messages postés
11
Date d'inscription
mardi 30 avril 2019
Statut
Membre
Dernière intervention
28 novembre 2024
Modifié le 11 nov. 2020 à 19:58
Modifié le 11 nov. 2020 à 19:58
Voilà, j'ai fais les modif, mais j'ai l'impression qu'il n'arrive pas à récupérer l'idarticle.
Voici l'erreur que j'ai :
Voici l'erreur que j'ai :
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.WrongClassException: Object [id=1] was not of the specified subclass [fr.eni.hibernate.entities.Articles] : Discriminator: Stylo at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154) at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1542) at org.hibernate.query.Query.getResultList(Query.java:165) at fr.eni.hibernate.entities.Main.main(Main.java:21) Caused by: org.hibernate.WrongClassException: Object [id=1] was not of the specified subclass [fr.eni.hibernate.entities.Articles] : Discriminator: Stylo at org.hibernate.loader.Loader.getInstanceClass(Loader.java:1945) at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1726) at org.hibernate.loader.Loader.getRow(Loader.java:1623) at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:740) at org.hibernate.loader.Loader.getRowsFromResultSet(Loader.java:1039) at org.hibernate.loader.Loader.processResultSet(Loader.java:990) at org.hibernate.loader.Loader.doQuery(Loader.java:959) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349) at org.hibernate.loader.Loader.doList(Loader.java:2850) at org.hibernate.loader.Loader.doList(Loader.java:2832) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2664) at org.hibernate.loader.Loader.list(Loader.java:2659) at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:506) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:400) at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1414) at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1565) at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1533) ... 2 more
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 019
>
Nathalie099
Messages postés
11
Date d'inscription
mardi 30 avril 2019
Statut
Membre
Dernière intervention
28 novembre 2024
11 nov. 2020 à 20:14
11 nov. 2020 à 20:14
Je n'ai pas eu ce problème en testant, les trois lignes insérées en base de données via ton SQL s'affichaient correctement.
Est ce que tu as la même erreur avec le type Ramette ?
La grosse différence avec mon code de test, c'est que je n'avais pas de persistence.xml (inutile avec Spring Boot), il y a peut-être une erreur dans ce fichier.
Essayes par exemple de ne mettre que la classe Articles (mais pas Stylo ni Ramette), ou éventuellement l'inverse, mettre uniquement Stylo et Ramette (mais pas Articles).
Est ce que tu as la même erreur avec le type Ramette ?
La grosse différence avec mon code de test, c'est que je n'avais pas de persistence.xml (inutile avec Spring Boot), il y a peut-être une erreur dans ce fichier.
Essayes par exemple de ne mettre que la classe Articles (mais pas Stylo ni Ramette), ou éventuellement l'inverse, mettre uniquement Stylo et Ramette (mais pas Articles).
Nathalie099
Messages postés
11
Date d'inscription
mardi 30 avril 2019
Statut
Membre
Dernière intervention
28 novembre 2024
12 nov. 2020 à 09:00
12 nov. 2020 à 09:00
J'ai tout essayé, mais j'ai toujours la même erreur, que ce soit en laissant la classe Articles dans persistence.xml ou en laissant Stylo et/ou Ramette.
Object [id=1] was not of the specified subclass [fr.eni.hibernate.entities.Articles] : Discriminator: Stylo
Object [id=1] was not of the specified subclass [fr.eni.hibernate.entities.Articles] : Discriminator: Stylo
Modifié le 11 nov. 2020 à 13:26
Merci pour vos réponses ! J'ai fais les modifications en enlevant les valeurs par défaut, en changeant le DiscriminatorType en String et en enlevant les constructeurs des classes Article, Ramette et Stylo, mais maintenant j'ai l'erreur suivante :
11 nov. 2020 à 14:09
Remarque : il pourrait également être utile de préciser le schéma de la base de données :