问题
I'm trying to generate my Entity class using javassist. Everything went well until I added the GeneratedValue annotation to the Id field. The @Id annotation works fine but when I add @GeneeratedValue I get an exception. This is my code:
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();
And this is the exception I get:
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)
It seems to be a problem with @GeneratedValue. When I use it alone whithout id I get this exception either. When I use eclipse debugger to watch variable values, I get get this
com.sun.jdi.InvocationException occurred invoking method.
instead of the annotation value. but for Id annotation it shows a javassist annotation object.
I'm new to javassist. Can anyone help me?
回答1:
I guess you're not looking for what happened anymore (I had the same problem today), but if you do...
When using constructor Annotation(ConstPool cp, CtClass clazz) javassist pre-creates all members for that Annotation Class (see Annotation.java, line 98).
In this case it's easy because there is an explicit comment: "// todo Enums are not supported right now." (line 101) and as you can see in javax.persistence.GeneratedValue there is a member called strategy of type GenerationType which is an Enum.
Though if the Annotation class have any Members of type class it won't work, causing a NullPointerException on the MemberValue.write method of descendant classes.
The solution or workaround is what you have done, using another constructor that leaves the members to be manually added, or (don't think this is a good option) set an instance for each class member in Annotation.
PS: I'm using javassist 3.12.1.GA
来源:https://stackoverflow.com/questions/3028304/javassist-annoations-problem