微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – @Embeddable类可以是私有的吗?

JPA规范中是否有任何描述有效@Embeddable类的内容?我看了但找不到任何东西.

我正在使用带有Hibernate(3.6.4.Final)和Spring(3.0.5)的EclipseLink(2.3.0-M7 – 完整构建字符串2.3.0.v20110429-r9282),并按照EclipseLink/Examples/MOXy/Spring/JAXBAnnotations所记录的方式设置了我的应用程序.其他目前工作,并已持续数月.我正在添加一个@Embeddable类并开始获得NPE.

下面是一些示例代码,我希望有人可以使用它来重现这个,如果它是EclipseLink的一个错误,因为我删除了EclipseLink库和配置(并恢复到Hibernate的实现),然后我不再获得NPE.

测试类broken.java

package x.y.z.model;

import javax.persistence.*;
import javax.xml.bind.annotation.*;
import java.io.Serializable;

@Entity
public class broken {
    @EmbeddedId
    private Pk pk = new Pk();

    @Embeddable 
    private static class Pk implements Serializable {
        @ManyToOne
        private String foo;

        public String getFoo() {
            return this.foo;
        }
        public void setFoo(String foo) {
            this.foo = foo;
        }
    }
}

我有的Spring bean配置是:

contextpath" value="x.y.z.model"/>

(参见上面的XMLHelper类链接)

最后,我将以下内容添加到jaxb.in​​dex:

broken

启动Spring应用程序时,我得到以下异常:

ERROR org.springframework.test.context.TestContextManager 324 - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@9b601d] to prepare test instance [x.y.z.service.AnyTest@198dc19]
java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:308)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:220)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:301)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:303)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runchild(SpringJUnit4ClassRunner.java:240)
    at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runchildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:115)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
    at $Proxy0.invoke(UnkNown Source)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jaxbMarshaller' defined in class path resource [applicationContext.xml]: Invocation of init method Failed; nested exception is org.springframework.oxm.UncategorizedMappingException: UnkNown JAXB exception; nested exception is
javax.xml.bind.JAXBException
 - with linked exception:
[java.lang.NullPointerException]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.initializeBean(AbstractAutowireCapablebeanfactory.java:1420)
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.doCreateBean(AbstractAutowireCapablebeanfactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.createBean(AbstractAutowireCapablebeanfactory.java:456)
    at org.springframework.beans.factory.support.Abstractbeanfactory$1.getobject(Abstractbeanfactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.Abstractbeanfactory.doGetBean(Abstractbeanfactory.java:288)
    at org.springframework.beans.factory.support.Abstractbeanfactory.getBean(Abstractbeanfactory.java:190)
    at org.springframework.beans.factory.support.DefaultListablebeanfactory.preInstantiateSingletons(DefaultListablebeanfactory.java:580)
    at org.springframework.context.support.AbstractApplicationContext.finishbeanfactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:84)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
    at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:280)
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:304)
    ... 31 more
Caused by: org.springframework.oxm.UncategorizedMappingException: UnkNown JAXB exception; nested exception is javax.xml.bind.JAXBException
 - with linked exception:
[java.lang.NullPointerException]
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.convertJaxbException(Jaxb2Marshaller.java:668)
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.getJaxbContext(Jaxb2Marshaller.java:335)
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.afterPropertiesSet(Jaxb2Marshaller.java:317)
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.invokeInitMethods(AbstractAutowireCapablebeanfactory.java:1477)
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.initializeBean(AbstractAutowireCapablebeanfactory.java:1417)
    ... 44 more
Caused by: javax.xml.bind.JAXBException
 - with linked exception:
[java.lang.NullPointerException]
    at org.eclipse.persistence.jaxb.JAXBContext$contextpathInput.createContextState(JAXBContext.java:661)
    at org.eclipse.persistence.jaxb.JAXBContext$contextpathInput.createContextState(JAXBContext.java:621)
    at org.eclipse.persistence.jaxb.JAXBContext.java.lang.reflect.Method.invoke(Method.java:597)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:128)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:249)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:372)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:337)
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.createJaxbContextFromcontextpath(Jaxb2Marshaller.java:355)
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.getJaxbContext(Jaxb2Marshaller.java:328)
    ... 47 more
Caused by: java.lang.NullPointerException
    at org.eclipse.persistence.jaxb.javamodel.Helper.isBuiltInJavaType(Helper.java:261)
    at org.eclipse.persistence.jaxb.compiler.Annotationsprocessor.shouldGenerateTypeInfo(Annotationsprocessor.java:1526)
    at org.eclipse.persistence.jaxb.compiler.Annotationsprocessor.processClass(Annotationsprocessor.java:1029)
    at org.eclipse.persistence.jaxb.compiler.Annotationsprocessor.processAdditionalClasses(Annotationsprocessor.java:994)
    at org.eclipse.persistence.jaxb.compiler.Annotationsprocessor.postBuildTypeInfo(Annotationsprocessor.java:576)
    at org.eclipse.persistence.jaxb.compiler.Annotationsprocessor.processClassesAndProperties(Annotationsprocessor.java:230)
    at org.eclipse.persistence.jaxb.compiler.Generator.contextpathInput.createContextState(JAXBContext.java:658)
    ... 60 more

如果我将@Embeddable类从private更改为public(并使用EclipseLink),则NPE不再出现.所以我有一个有效的解决方案,但想了解原因.

最佳答案
JPA 2.0 Specification声明可嵌入类必须遵守为实体规定的相同要求.这些要求在说明书的第2.1节中说明,并声明:

  • The entity class must have a no-arg constructor. It may have other constructors as well. The no-arg constructor must be public or protected.
  • The entity class must a be top-level class. An enum or interface must not not be
    designated as an entity.
  • The entity class must not be final. No methods or persistent instance variables of the entity class may be final.

因此,我认为影响你的是可嵌入类不是顶级类,加上它是私有的.

你可能想尝试一下.即使这不是原因,您也可以考虑遵循标准的建议,否则,您无法保证您的代码符合它.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐