2017-06-05 5 views
0

exemple de base de données existante (desc ci-dessous): enter image description hereMapping hasOne avec belongsTo dans Grails

Je la table parent qui a composite clé primaire, id1 générée automatiquement comme SERIAL (1), ID2 avec seulement une valeur par défaut. La table enfant a exactement la même clé primaire, c'est-à-dire également la clé étrangère de la table parent.

La table enfant est quelque chose comme une table "plus" ou une table parent extandie. Nous avons besoin de colonnes supplémentaires dans la table PArent mais nous ne pouvons pas changer la table parent. Ils ont donc créé pour nous la table enfant avec des informations supplémentaires, ajouter la clé étrangère de la table des parents à la table des enfants et faire également cette clé composite primaire :)

je tente de la carte en Grails cette façon:

Parent .groovy

package test 
class Parent implements Serializable{ 
    Integer id1 
    Integer id2 
    String parentDesc 

    static hasOne = [child: Child] 

    static mappedBy = [child: 'parent'] 

    static constraints = { 
     child nullable:true 
    } 

    static mapping = { 
     table 'parent' 
     id   composite: ['id1', 'id2'] 
     id1  column: 'id1' 
     id2  column: 'id2' 
     parentDesc column: 'parent_desc' 
    } 
} 

Child.groovy

package test 

import java.io.Serializable 

class Child implements Serializable{ 
    Integer id1 
    Integer id2 
    Parent parent 
    String childDesc 

    static belongsTo = [parent: Parent] 

    static mapping = { 
     table 'child' 


     id  composite: ['id1', 'id2'] 
     id1  column: 'id1' 
     id2  column: 'id2' 
     childDesc column: 'child_desc' 
     columns { 
     parent(insertable: false, updateable: false) { 
      column name: 'id1' 
      column name: 'id2' 
     } 
    } 
} 

} Le parent a un ou zéro enfant avec la clé composite id1, id2. L'enfant appartient à Parent (enregistrer et supprimer avec le parent), a la clé primaire Parent clé étrangère, et aussi cette clé étrangère composite est également sa clé primaire.

Hibernate ne peut pas renvoyer des valeurs lorsqu'il y a des lignes (la table vide n'est pas un problème :) - Je pense que son même bug a signalé here (mais cette fois déjà résolu).

Fiche technique: Base de données: MaxDB (héritage) a également testé sur H2 embarqué

  • grailsVersion = 3.2.9
  • "Compile org.grails.plugins: hibernate5"
  • compilez "org.hibernate: hibernate-core: 5.1.3.Final"
  • compile 'org.hi Bernate: mise en veille prolongée-java8: 5.1.2.Final »
  • compilation 'com.h2database: h2: 1.4.193'
  • compilation "com.sap:sapdbc:7.4.4"

projet de test complet: dropbox

Stacktrace:

[2m2017-06-05 13:59:26.063[0;39m [31mERROR[0;39m [2m---[0;39m [2m[nio-8080-exec-1][0;39m [36mo.g.web.errors.GrailsExceptionResolver [0;39m [2m:[0;39m NullPointerException occurred when processing request: [GET]/
Stacktrace follows: 

java.lang.reflect.InvocationTargetException: null 
    at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:211) 
    at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:188) 
    at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) 
    at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55) 
    at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77) 
    at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:748) 
Caused by: java.lang.NullPointerException: null 
    at org.hibernate.persister.entity.AbstractEntityPersister.loadByUniqueKey(AbstractEntityPersister.java:2172) 
    at org.hibernate.type.EntityType.loadByUniqueKey(EntityType.java:692) 
    at org.hibernate.type.EntityType.resolve(EntityType.java:434) 
    at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:151) 
    at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:125) 
    at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1139) 
    at org.hibernate.loader.Loader.processResultSet(Loader.java:998) 
    at org.hibernate.loader.Loader.doQuery(Loader.java:936) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:342) 
    at org.hibernate.loader.Loader.doList(Loader.java:2622) 
    at org.hibernate.loader.Loader.doList(Loader.java:2605) 
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2434) 
    at org.hibernate.loader.Loader.list(Loader.java:2429) 
    at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:109) 
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1787) 
    at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:363) 
    at org.grails.orm.hibernate.query.AbstractHibernateQuery.listForCriteria(AbstractHibernateQuery.java:700) 
    at org.grails.orm.hibernate.HibernateGormStaticApi$_list_closure1.doCall(HibernateGormStaticApi.groovy:87) 
    at org.grails.orm.hibernate.GrailsHibernateTemplate.doExecute(GrailsHibernateTemplate.java:286) 
    at org.grails.orm.hibernate.GrailsHibernateTemplate.execute(GrailsHibernateTemplate.java:230) 
    at org.grails.orm.hibernate.GrailsHibernateTemplate.execute(GrailsHibernateTemplate.java:116) 
    at org.grails.orm.hibernate.HibernateGormStaticApi.list(HibernateGormStaticApi.groovy:73) 
    at org.grails.orm.hibernate.HibernateGormStaticApi.list(HibernateGormStaticApi.groovy:72) 
    at org.grails.datastore.gorm.GormEntity$Trait$Helper.list(GormEntity.groovy:654) 
    at test.ParentController.$tt__index(ParentController.groovy:10) 
    at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96) 
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133) 
    at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93) 
    ... 14 common frames omitted 
+0

Il n'y a aucun problème avec hasMany au sein de la même configuration. Probablement bug en hibernation? –

Répondre

0

Je sais que ce Qué stion est un peu vieux, mais j'avais ce que je pense être le même problème que le vôtre. Quoi qu'il en soit, après un peu de débogage et de recherche, j'ai commencé à travailler. Tout ce que je devais faire était de changer le comportement d'extraction en 'join' afin qu'il récupère le parent et l'enfant dans la même requête sql. Notez que cela peut signifier un goulot d'étranglement des performances dépendant de votre cas d'utilisation.

Edit: refresh() ne fonctionne toujours pas si