Javassist注释问题

发布于 2024-09-05 22:07:11 字数 2335 浏览 8 评论 0原文

我正在尝试使用 javassist 生成我的实体类。一切都很顺利,直到我将 GenerationValue 注释添加到 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)

这似乎是 @GenerateValue 的问题。当我单独使用它而没有 id 时,我也会遇到此异常。当我使用 eclipse 调试器观察变量值时,我得到的是这个

com.sun.jdi.InvocationException occurred invoking method.

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

徒留西风 2024-09-12 22:07:11

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

当使用构造函数 Annotation(ConstPool cp, CtClass clazz) javassist 预先创建该注释类的所有成员(请参阅Annotation.java,第 98 行)。

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

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

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

PS:我使用的是javassist 3.12.1.GA

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文