4

我正在尝试使用 javassist 生成我的实体类。一切都很顺利,直到我将 GeneratedValue 注释添加到 Id 字段。@Id 注释工作正常,但是当我添加 @GeneeratedValue 时出现异常。这是我的代码:

  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();

这是我得到的例外:

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)

@GeneratedValue 似乎有问题。当我在没有 id 的情况下单独使用它时,我也会得到这个异常。当我使用 eclipse 调试器观察变量值时,我得到了这个

com.sun.jdi.InvocationException occurred invoking method.

而不是注释值。但对于 Id 注释,它显示一个 javassist 注释对象。

我是 javassist 的新手。谁能帮我?

4

1 回答 1

6

我想您不再寻找发生的事情(我今天遇到了同样的问题),但是如果您这样做...

当使用构造函数 Annotation(ConstPool cp, CtClass clazz) javassist 为该 Annotation Class 预先创建所有成员(参见 Annotation.java,第 98 行)。

在这种情况下很容易,因为有一个明确的注释:“// todo Enums are not supported now.” (第 101 行),正如您在 javax.persistence.GeneratedValue 中看到的,有一个名为策略的成员,类型为 GenerationType,它是一个枚举。

尽管如果 Annotation 类有任何类型为类的成员,它将无法工作,从而导致后代类的 MemberValue.write 方法出现 NullPointerException。

解决方案或解决方法就是您所做的,使用另一个构造函数让成员手动添加,或者(不要认为这是一个好的选择)为 Annotation 中的每个类成员设置一个实例。

PS:我正在使用 javassist 3.12.1.GA

于 2011-05-02T21:47:00.893 回答