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!
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
@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