jpa选择new with embedded key throws exception

时间:2013-01-25 10:23:09

标签: jpa eclipselink

尝试运行以下命名查询时出现异常

@NamedQuery(name = "software.listAssemblies", query = "SELECT distinct NEW com.blackbox.dao.AssemblyToBootloaderDTO(s.id.assemblyId, s.filename) FROM Software s where s.id.platformId = :platformId and s.id.txaddress = :txaddress and s.filetype = 'SBL';")

如果我删除对AssemblyToBootloaderDTO的引用,则查询读取

@NamedQuery(name = "software.listAssemblies", query = "SELECT distinct s.id.assemblyId, s.filename FROM Software s where s.id.platformId = :platformId and s.id.txaddress = :txaddress and s.filetype = 'SBL';")

然后查询成功运行,按预期返回object []列表。

我的应用程序中有几个命名查询通过SELECT NEW创建DTO对象,运行没有问题,但这是我尝试使用嵌入式密钥中的字段的第一个DTO所以我猜测我在这里缺少一些语法。我需要做什么才能使映射到DTO类工作?

@Entity
@Table(name="software")
@NamedQueries({
@NamedQuery(name = "software.listBootLoaders", query = "SELECT distinct s.filename FROM Software s where s.id.platformId = :platformId and s.id.txaddress = :txaddress and s.filetype = 'SBL';"),
@NamedQuery(name = "software.listAssemblies", query = "SELECT distinct NEW com.blackbox.dao.AssemblyToBootloaderDTO(s.id.assemblyId, s.filename) FROM Software s where s.id.platformId = :platformId and s.id.txaddress = :txaddress and s.filetype = 'SBL';")

})
public class Software implements Serializable {
private static final long serialVersionUID = 1L;

@EmbeddedId
private SoftwarePK id;

@Column(name="fileName", length=32)
private String filename;

@Column(name="fileType", length=8)
private String filetype;

@Column(name="predecessor", length=64)
private String predecessor;

@Column(name="successor", length=64)
private String successor;

//bi-directional many-to-one association to Hardware
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumns({
    @JoinColumn(name="assemblyId", referencedColumnName="assemblyId", nullable=false, insertable=false, updatable=false),
    @JoinColumn(name="busId", referencedColumnName="busId", nullable=false, insertable=false, updatable=false),
    @JoinColumn(name="hardwareId", referencedColumnName="hardwareId", nullable=false, insertable=false, updatable=false),
    @JoinColumn(name="platformId", referencedColumnName="platformId", nullable=false, insertable=false, updatable=false),
    @JoinColumn(name="txAddress", referencedColumnName="txAddress", nullable=false, insertable=false, updatable=false)
    })
private Hardware hardware;

public Software() {
}

public SoftwarePK getId() {
    return this.id;
}

public void setId(SoftwarePK id) {
    this.id = id;
}
... getters/setters omitted

嵌入式密钥;

@Embeddable
public class SoftwarePK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;

@Column(name="platformId",unique=true, nullable=false)
private int platformId;

@Column(name="busId", unique=true, nullable=false)
private int busid;

@Column(name="txAddress", unique=true, nullable=false, length=3)
private String txaddress;

@Column(name="assemblyId",unique=true, nullable=false, length=64)
private String assemblyId;

@Column(name="hardwareId",unique=true, nullable=false, length=64)
private String hardwareId;

@Column(name="sequence",unique=true, nullable=false)
private int sequence;

@Column(name="softwareId",unique=true, nullable=false, length=64)
private String softwareId;

    public SoftwarePK() {
    }

    getters/setters omitted.

DTO;

public class AssemblyToBootloaderDTO {

private String assemblyId;
private String softwareBootloaderId;


public AssemblyToBootloaderDTO(String assemblyId,
        String softwareBootloaderId) {

    this.assemblyId = assemblyId;
    this.softwareBootloaderId = softwareBootloaderId;
}


public String getAssemblyId() {
    return assemblyId;
}


public String getSoftwareBootloaderId() {
    return softwareBootloaderId;
}

}

和例外;

Exception [EclipseLink-6052] (Eclipse Persistence Services - 2.1.3.v20110304-r9073): org.eclipse.persistence.exceptions.QueryException
Exception Description: An outer join (getAllowingNull or anyOfAllowingNone) is only valid for OneToOne, OneToMany, ManyToMany, AggregateCollection and DirectCollection Mappings, and cannot be used for the mapping [org.eclipse.persistence.mappings.DirectToFieldMapping[assemblyId-->software.assemblyId]].
org.eclipse.persistence.exceptions.QueryException.outerJoinIsOnlyValidForOneToOneMappings(QueryException.java:924)
org.eclipse.persistence.internal.expressions.QueryKeyExpression.validateNode(QueryKeyExpression.java:863)
org.eclipse.persistence.expressions.Expression.normalize(Expression.java:3009)
org.eclipse.persistence.internal.expressions.DataExpression.normalize(DataExpression.java:342)
org.eclipse.persistence.internal.expressions.QueryKeyExpression.normalize(QueryKeyExpression.java:612)
org.eclipse.persistence.internal.expressions.QueryKeyExpression.normalize(QueryKeyExpression.java:599)
org.eclipse.persistence.internal.expressions.SQLSelectStatement.normalize(SQLSelectStatement.java:1311)
org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.buildReportQuerySelectStatement(ExpressionQueryMechanism.java:560)
org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.buildReportQuerySelectStatement(ExpressionQueryMechanism.java:506)
org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.prepareReportQuerySelectAllRows(ExpressionQueryMechanism.java:1527)
org.eclipse.persistence.queries.ReportQuery.prepareSelectAllRows(ReportQuery.java:1298)
org.eclipse.persistence.queries.ReadAllQuery.prepare(ReadAllQuery.java:625)
org.eclipse.persistence.queries.ReportQuery.prepare(ReportQuery.java:1047)
org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:509)
org.eclipse.persistence.queries.ObjectLevelReadQuery.checkPrepare(ObjectLevelReadQuery.java:820)
org.eclipse.persistence.queries.DatabaseQuery.prepareCall(DatabaseQuery.java:1588)
org.eclipse.persistence.internal.jpa.EJBQueryImpl.getDatabaseQueryInternal(EJBQueryImpl.java:568)
org.eclipse.persistence.internal.jpa.EntityManagerImpl.createNamedQuery(EntityManagerImpl.java:1001)
com.blackbox.dao.JpaSoftwareDao.listAssemblies(JpaSoftwareDao.java:168)
com.blackbox.services.Services.getAssemblyNames(Services.java:571)
com.blackbox.genesis.ccfeditor.services.NanocomService.buildSource(NanocomService.java:48)
com.blackbox.genesis.actions.ccfedit.DownloadCCForNanocom.execute(DownloadCCForNanocom.java:35)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:452)
com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:291)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:254)
com.blackbox.x.interceptors.LicenseInterceptor.intercept(LicenseInterceptor.java:75)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:263)
org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:133)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:267)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:142)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:166)
com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.blackbox.x.interceptors.Log4jMDCInterceptor.intercept(Log4jMDCInterceptor.java:51)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.blackbox.x.interceptors.RedirectMessageInterceptor.doIntercept(RedirectMessageInterceptor.java:78)
com.blackbox.x.interceptors.RedirectMessageInterceptor.intercept(RedirectMessageInterceptor.java:63)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:485)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter.doFilter(StrutsExecuteFilter.java:88)
com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129)
com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter.doFilter(StrutsPrepareFilter.java:82)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:125)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)

2 个答案:

答案 0 :(得分:0)

似乎是构造函数元素中的连接问题。

尝试最新的/ 2.4版本,我猜这已经修复了。如果仍然没有运气,请记录一个错误。

答案 1 :(得分:0)

似乎是一个jpa /实现错误,我正在运行eclipselink 2.3并得到同样的问题。

作为替代方法,删除@Embeddable和@EmbeddedId并在实体级别使用@IdClass,而在关键字段使用@Id,即:

@Table(name = "MY_TABLE")
@IdClass(value=MyTableId.class)
public class MyTableEntity implements Serializable {
    private static final long serialVersionUID = 1000L;

    public static class MyTableId implements Serializable {
        private static final long serialVersionUID = 1000L;
        private Integer keyFieldOne;
        private String keyFieldTwo;

        public MyTableId() {
            super();
        }

        public MyTableId(Integer keyFieldOne, String keyFieldTwo) {
            this.keyFieldOne = keyFieldOne;
            this.keyFieldTwo = keyFieldTwo;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            MyTableId myTableId = (MyTableId)obj;
            return Objects.equal(keyFieldOne, myTableId.keyFieldOne) && Objects.equal(keyFieldTwo, myTableId.keyFieldTwo);
        }

        @Override
        public int hashCode() {
            return Objects.hashCode(keyFieldOne, keyFieldTwo);
        }
    }

    @Id
    @Column(name = "KEY_FIELD_ONE", nullable = false)
    private Integer keyFieldOne;
    @Id
    @Column(name = "KEY_FIELD_TWO", nullable = false, length = 8)
    private String keyFieldTwo;

    ...

}

注意我使用google guava进行哈希码和等于覆盖