代码之家  ›  专栏  ›  技术社区  ›  javydreamercsw

具有空值的JPA联接列

  •  2
  • javydreamercsw  · 技术社区  · 16 年前

    我有一个查询在普通的SQL中工作,但不在JPA中工作,无法找出原因。你可以从标题猜到,我有一个线索,但我不知道如何“修复”它。

    以下是实际的重要代码:

    @Id 
    @Basic(optional = false) 
    @Column(name = "id", nullable = false) 
    private Integer id; 
    
    @Basic(optional = false) 
    @Column(name = "read_permission", nullable = false) 
    private boolean readPermission; 
    
    @Basic(optional = false) 
    @Column(name = "write_permission", nullable = false) 
    private boolean writePermission; 
    
    @Basic(optional = false) 
    @Column(name = "execute_permission", nullable = false) 
    private boolean executePermission; 
    
    @Basic(optional = false) 
    @Column(name = "admin_permission", nullable = false) 
    private boolean adminPermission; 
    
    @JoinColumn(name = "xinco_core_data_id", referencedColumnName = "id", nullable=true) 
    @ManyToOne(fetch = FetchType.LAZY) 
    private XincoCoreData xincoCoreDataId; 
    @JoinColumn(name = "xinco_core_group_id", referencedColumnName = "id", nullable=true) 
    @ManyToOne(fetch = FetchType.LAZY) 
    private XincoCoreGroup xincoCoreGroupId; 
    
    @JoinColumn(name = "xinco_core_node_id", referencedColumnName = "id", nullable=true) 
    @ManyToOne(fetch = FetchType.LAZY) 
    private XincoCoreNode xincoCoreNodeId; 
    
    @JoinColumn(name = "xinco_core_user_id", referencedColumnName = "id", nullable=true) 
    @ManyToOne(fetch = FetchType.LAZY) 
    private XincoCoreUser xincoCoreUserId; 
    

    下面是有效的SQL:

    select * from xinco_core_ace where xinco_core_user_id = 1 order by xinco_core_user_id, xinco_core_node_id, xinco_core_data_id; 
    

    我想做的是:

    SELECT xca FROM XincoCoreAce xca WHERE xca.xincoCoreUserId.id = 1 ORDER BY xca.xincoCoreUserId.id, xca.xincoCoreGroupId.id, xca.xincoCoreNodeId.id, xca.xincoCoreDataId.id
    

    我认为,问题在于xca.xincoreuserid.id、xca.xincoregroupid.id、xca.xincororneodeid.id、xca.xincoroledaid.id可以为空。

    有什么想法吗?希望更容易阅读:p

    3 回复  |  直到 13 年前
        1
  •  2
  •   Repoker    13 年前

    我也遇到了一个更简单的问题:

    select t from Task t where t.worker is not null order by t.worker.normalizedName
    

    发现属性worker为空(未分配任务)的任何任务结果实体都将被丢弃。后来我发现这是因为JPA中的路径导航是使用内部连接(规范这么说的)完成的,并且这将排除部分路径为空的任何结果。

    此错误报告准确描述了问题:

    https://bugs.eclipse.org/bugs/show_bug.cgi?id=363798

    不幸的是, 这不是一个实现错误 为了避免这种情况,您必须重构您的实体/查询。

        2
  •  1
  •   javydreamercsw    16 年前

    这是实际完成的查询(使用EclipseLink日志记录):

    SELECT t1.id, t1.write_permission, t1.admin_permission, t1.execute_permission, t1.read_permission, t1.xinco_core_user_id, t1.xinco_core_data_id, t1.xinco_core_group_id, t1.xinco_core_node_id FROM xinco_core_data t4, xinco_core_node t3, xinco_core_group t2, xinco_core_ace t1, xinco_core_user t0 WHERE ((t3.id = ?) AND ((((t3.id = t1.xinco_core_node_id) AND (t0.id = t1.xinco_core_user_id)) AND (t2.id = t1.xinco_core_group_id)) AND (t4.id = t1.xinco_core_data_id))) ORDER BY t0.id ASC, t2.id ASC, t3.id ASC, t4.id ASC bind => [1]
    

    出于某种原因,ORDERBY添加了许多表交叉检查,其中有空值会使结果变为空。

    删除order by会得到所需的结果(当然是无序的)。

    看到这个EclipseLink bug

        3
  •  0
  •   kovica    16 年前

    我不是这里的JPA专家,但我会尝试获取数据库上运行的实际SQL。也许fetchtype.lazy与问题有关?