2010-09-24 7 views
0

J'ai quelques classes de domaine, et je veux pouvoir remplir une nouvelle classe Domain et la conserver dans la base de données via l'un de mes contrôleurs. Voici mes classesComment créer des objets Domaine valides à l'exécution dans Grails

class Employee implements Comparable 
{ 
    static hasMany = [education:Education] 
    static mapping = { 
     education cascade:"all,delete-orphan", lazy:false 
    } 
    List<Education> education = new ArrayList<Education>(); 
} 


public class Education implements Comparable 
{ 
    static belongsTo = [employee:Employee] 
    String collegeName 
    String areaOfStudy 
    String yearGranted 
    Date lastModified 
    Boolean inProcess = false; 
    EducationType type = new EducationType(name:"None"); 
} 


class EducationType 
{ 
    String name=""; 
} 

Maintenant, je veux créer une nouvelle entrée Éducation pour un employé particulier de ce contrôleur.

 def employee = Employee.get(session.empid); 
     EducationType et = new EducationType(name:'JD') 
     Education ed1 = new Education(collegeName:'Harvard1', areaOfStudy:'Law', yearGranted:'2015', type:et, lastModified:new Date(), employee:employee) 

     employee.addToEducation(ed1) 
     employee.save() 

Pour une raison quelconque ce ne se comporte pas comme prévu et je reçois cette exception:

2010-09-24 10:56:01,503 [http-8080-1] ERROR errors.GrailsExceptionResolver - not-null property references a null or transient value: Education.type; nested exc 
eption is org.hibernate.PropertyValueException: not-null property references a null or transient value: Education.type 
org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value: Education.type; nested exception is org.hiberna 
te.PropertyValueException: not-null property references a null or transient value: Education.type 
     at org.jsecurity.web.servlet.JSecurityFilter.doFilterInternal(JSecurityFilter.java:382) 
     at org.jsecurity.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:180) 
     at java.lang.Thread.run(Thread.java:619) 
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: Education.type 
     ... 3 more 

je peux obtenir ce pour aller loin en enregistrant d'abord la EducationType avec un et.save() puis enregistrer l'objet Education avec ed.save() et enfin enregistrer l'employé.

Pourquoi est-ce nécessaire? Mon mappage ne dit-il pas qu'une sauvegarde sur l'employé devrait se répercuter sur les objets non persistants qui sont maintenant associés à l'employé?

Aussi - pourquoi dois-je explicitement ajouter un employé quand j'initialise l'objet Education? Il est spécifié dans l'objet belongsTo, et il semble que quand je fais l'appel de employee.addToEducation(), il devrait être ramassé automatiquement, n'est-ce pas?

Merci!

Répondre

0

Votre Education to EducationType est défini comme un simple one-to-one. Pour passer de Education à EducationType, je pense que vous pouvez faire en sorte que ces derniers appartiennent à l'ancien. Consultez la section 5.2.1.1 du guide de l'utilisateur. Notez que vous devez faire attention à la sémantique de persistance que vous voulez. Voulez-vous vraiment que EducationTypes soit leur propre entité?

Je pense que vous devez ajouter l'employé à Éducation parce que vous avez un un à plusieurs. Les deux côtés de la relation doivent être mis en place. addToEducation fonctionne pour ajouter au côté propriétaire de la relation un membre de la collection. Évidemment, il ne définit pas la relation du côté possédé au côté propriétaire.

---- ---- modifier

Je viens de regarder les documents parce que votre deuxième erreur semble étrange méthode

« Le addTo * est une méthode dynamique qui utilise une association pour ajouter automatiquement des instances Il configure également automatiquement les relations bidirectionnelles de sorte que les deux parties de la relation aient été établies. "

Il semble donc que addTo devrait mettre les deux côtés de la relation ... Si vous prenez l'employé: employé de votre création de l'éducation, cela ne fonctionne pas?

+0

Merci à propos de la note en cascade - qui semble avoir résolu mes problèmes. Pourquoi est-ce le cas de toute façon? Je pensais par défaut sur créer en cascade était le comportement. Les paramètres par défaut ne sont-ils plus disponibles une fois que vous avez défini un mappage? Quant à mon deuxième problème, je n'arrive pas à le reproduire après avoir résolu le problème en cascade - peut-être que c'était un problème avec l'objet qui n'était pas valide avant ou quelque chose. Si je peux y arriver à nouveau, je posterai ici. – Derek

+0

@Derek, je ne pense pas que la cascade est toujours la valeur par défaut avec hibernate non-grails activé; dans les grails, ils pourraient faire certaines choses pour aider, mais vous devez avoir les docs prêts à confirmer. – hvgotcodes

Questions connexes