我在 NetBeans 8.0.2 上使用 OpenJPA 2.0 和 TomEE 1.7.2,在我在实体类中添加一些 Java 8 代码之前它工作正常,但现在我在启动 TomEE 时遇到 StringIndexOutOfBoundsException。
我有一个类(class)电话
@Entity
@Table(name = "PHONES")
public class Phone implements Serializable, Cloneable {
@Id
@Column(name = "PHONE_ID", nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "PHONE_NUMBER", nullable = false)
private String number;
@ManyToOne
@JoinColumn(name = "PERSON_ID", nullable = false)
private Person owner;
}
我有一个类 Person。
@Entity
@Table(name = "PEOPLE")
public class Person implements Serializable, Cloneable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "PERSON_ID")
private long id;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch = FetchType.EAGER)
private Set<Phone> phones;
}
我有一个 setPhones 方法,它使用 for 来正确设置所有者:
public void setPhones(Set<Phone> phones) {
if (phones != null && !phones.isEmpty()) {
for (Phone phone : phones) {
if (phone != null) {
phone.setOwner(this);
}
}
}
this.phones = phones;
}
然后,我改用 java 8 流/过滤器
public void setPhones(Set<Phone> phones) {
if (phones != null && !phones.isEmpty()) {
phones.stream().filter((phone) -> (phone != null)).forEach((phone) -> {
phone.setOwner(this);
});
}
this.phones = phones;
}
进行此更改后,我在启动时收到此消息:
WARNING: An exception was thrown while attempting to perform class file transformation on "com.mydomain.Person": java.lang.StringIndexOutOfBoundsException: String index out of range: 29789
at java.lang.String.checkBounds(String.java:373)
at java.lang.String.<init>(String.java:413)
at serp.bytecode.lowlevel.ConstantPoolTable.readString(ConstantPoolTable.java:112)
at serp.bytecode.lowlevel.ConstantPoolTable.readString(ConstantPoolTable.java:174)
at org.apache.openjpa.enhance.PCClassFileTransformer.isEnhanced(PCClassFileTransformer.java:241)
at org.apache.openjpa.enhance.PCClassFileTransformer.needsEnhance(PCClassFileTransformer.java:195)
at org.apache.openjpa.enhance.PCClassFileTransformer.transform0(PCClassFileTransformer.java:140)
at org.apache.openjpa.enhance.PCClassFileTransformer.transform(PCClassFileTransformer.java:127)
at org.apache.openjpa.persistence.PersistenceProviderImpl$ClassTransformerImpl.transform(PersistenceProviderImpl.java:292)
at org.apache.openejb.persistence.PersistenceUnitInfoImpl$PersistenceClassFileTransformer.transform(PersistenceUnitInfoImpl.java:362)
at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2957)
at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1210)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1690)
at org.apache.tomee.catalina.LazyStopWebappClassLoader.loadClass(LazyStopWebappClassLoader.java:171)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
at org.apache.openejb.cdi.CdiScanner.load(CdiScanner.java:299)
at org.apache.openejb.cdi.CdiScanner.process(CdiScanner.java:248)
at org.apache.openejb.cdi.CdiScanner.init(CdiScanner.java:182)
at org.apache.openejb.cdi.OpenEJBLifecycle.startApplication(OpenEJBLifecycle.java:180)
at org.apache.openejb.cdi.ThreadSingletonServiceImpl.initialize(ThreadSingletonServiceImpl.java:160)
at org.apache.openejb.cdi.CdiBuilder.build(CdiBuilder.java:41)
at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:846)
at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:652)
at org.apache.tomee.catalina.TomcatWebAppBuilder.startInternal(TomcatWebAppBuilder.java:1261)
at org.apache.tomee.catalina.TomcatWebAppBuilder.configureStart(TomcatWebAppBuilder.java:1100)
at org.apache.tomee.catalina.GlobalListenerSupport.lifecycleEvent(GlobalListenerSupport.java:130)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5416)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:677)
at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1912)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)
我的“解决方案”是恢复以前的方法,它工作正常。但我希望能够在我的项目中使用 Java 8。 难道我做错了什么?如果是这样,什么?
最佳答案
看起来 TomEE 1.7.2 使用旧版本 (1.14.1) 的“serp”库来对实体 bean 进行字节码操作。不幸的是,该版本不支持使用一些新的 Java 8 功能(尤其是 lambda)的类。您可以尝试更新到最新版本的 serp(尽管可能存在不兼容),看看是否可以正常工作。
检查this serp issue和 this OpenJPA issue这两个问题似乎都已修复(这意味着最终 TomEE 应该进行更新,以在其 JPA 实体 bean 中获得完整的 Java 8 支持)。他们可能会告诉您是否/如何手动更新 TomEE 1.7.2 中的库以更快获得支持。
关于java - 使用流过滤器的实体在带有 TomEE 的 OpenJPA 上产生 StringIndexOutOfBoundsException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32832986/