2010-06-12 6 views
4

J'essaie de générer ma classe Entity en utilisant javassist. Tout s'est bien passé jusqu'à ce que j'ajoute l'annotation GeneratedValue au champ Id. L'annotation @Id fonctionne correctement, mais lorsque j'ajoute @GeneeratedValue, j'obtiens une exception. Ceci est mon code:Problème d'annotation de Javassist

ClassPool cp = ClassPool.getDefault(); 
    CtClass ctClass = cp.makeClass("test.Snake"); 
    ClassFile classFile = ctClass.getClassFile(); 
    classFile.setVersionToJava5(); 

    AnnotationsAttribute attribute = new AnnotationsAttribute(classFile.getConstPool(), AnnotationsAttribute.visibleTag); 

    Annotation idAnnotation = new Annotation(classFile.getConstPool(), ClassPool.getDefault().get("javax.persistence.Id")); 
    attribute.addAnnotation(idAnnotation); 

    Annotation gvAnnotation = new Annotation(classFile.getConstPool(), ClassPool.getDefault().get("javax.persistence.GeneratedValue")); 
    attribute.addAnnotation(gvAnnotation); 

    CtField idField = new CtField(ClassPool.getDefault().get("java.lang.Long"), "id", ctClass); 
    idField.getFieldInfo().addAttribute(attribute); 
    ctClass.addField(idField); 

    CtField nameField = new CtField(ClassPool.getDefault().get("java.lang.String"), "name", ctClass); 
    ctClass.addField(nameField); 

    AnnotationsAttribute attr = new AnnotationsAttribute(classFile.getConstPool(), AnnotationsAttribute.visibleTag); 
    Annotation annotation = new Annotation(classFile.getConstPool(), ClassPool.getDefault().get("javax.persistence.Entity")); 
    attr.addAnnotation(annotation); 
    classFile.addAttribute(attr); 

    snakeClass = ctClass.toClass(); 
    newInstance = snakeClass.newInstance(); 

Et voici l'exception que je reçois:

java.lang.NullPointerException 
at javassist.bytecode.ConstPool.getUtf8Info(ConstPool.java:565) 
at javassist.bytecode.annotation.EnumMemberValue.getValue(EnumMemberValue.java:98) 
at javassist.bytecode.annotation.EnumMemberValue.write(EnumMemberValue.java:116) 
at javassist.bytecode.annotation.Annotation.write(Annotation.java:316) 
at javassist.bytecode.AnnotationsAttribute.setAnnotations(AnnotationsAttribute.java:246) 
at javassist.bytecode.AnnotationsAttribute.addAnnotation(AnnotationsAttribute.java:211) 
at ClassLoadingTest.javassitTest(ClassLoadingTest.java:56) 

Il semble être un problème avec @GeneratedValue. Quand je l'utilise seul sans identifiant, je reçois cette exception non plus. Lorsque j'utilise débogueur Eclipse pour regarder les valeurs des variables, je reçois obtenir ce

com.sun.jdi.InvocationException occurred invoking method. 

au lieu de la valeur d'annotation. mais pour l'annotation Id, il montre un objet d'annotation javassiste.

Je suis nouveau à javassist. Quelqu'un peut-il m'aider?

+1

En fait, j'ai trouvé la solution. Je jouais avec les constructeurs des Annotations et celui qui prend le nom de la classe sous forme de chaîne et ensuite le constPool fonctionne bien! Bien que je ne savais pas pourquoi! Annotation gvAnnotation = new Annotation ("javax.persistence.GeneratedValue", classFile.getConstPool()); – Wickoo

Répondre

5

Je suppose que vous n'êtes pas à la recherche de ce qui est arrivé plus (j'ai eu le même problème aujourd'hui), mais si vous ...

Lors de l'utilisation constructeur Annotation (ConstPool cp, CtClass clazz) javassist pré-crée tous les membres de cette classe d'annotation (voir Annotation.java, ligne 98).

Dans ce cas, c'est facile car il y a un commentaire explicite: "// todo Les Enums ne sont pas supportés pour l'instant." (ligne 101) et comme vous pouvez le voir dans javax.persistence.GeneratedValue, il y a un membre appelé stratégie de type GenerationType qui est un Enum.

Cependant, si la classe Annotation a des membres de classe type, elle ne fonctionnera pas, provoquant une exception NullPointerException sur la méthode MemberValue.write des classes descendantes. La solution ou solution de contournement est ce que vous avez fait, en utilisant un autre constructeur qui laisse les membres à ajouter manuellement, ou (ne pensez pas que ce soit une bonne option) définir une instance pour chaque membre de classe dans Annotation. PS: J'utilise javassist 3.12.1.GA

Questions connexes