2

と の 2 つの JPA エンティティがVirtualLotありVirtualFilesます。VirtualFiles伸びVirtualInodeます。「VirtualLot は VirtualFiles を含むことができる」「VirtualFile は複数の VirtualLots に関連付けることができるVirtualLot」の間にVirtualFilesはManyToMany の関係があり、 エンティティは次のように定義されます。

VirtualFile.java

@Entity
@Table(name = "FIL_FILE")
public class VirtualFile extends VirtualInode {
    //[...]
}

VirtualInode.java

@Entity
@Table(name = "INO_INODE")
@Inheritance(strategy = InheritanceType.JOINED)
public class VirtualInode implements Serializable {
    private Long id; /* The PK */
    private long size = 0L; /* The size */
    // [...]

    /**
     * Default constructor
     */
    public VirtualInode() {
        super();
    }

    /**
     * @return the id
     */
    @Id
    @Column(name = "INO_ID", nullable = false)
    public Long getId() {
        return id;
    }

    /**
     * @return the size
     */
    @Column(name = "INO_SIZE", nullable = false)
    public long getSize() {
        return size;
    }

    //[...]
}

VirtualLot.java

@Entity
@Table(name = "VLT_VIRTUAL_LOT")
public class VirtualLot implements Serializable {
    private Long id; /* The PK */
    private Collection<VirtualFile> files;

    /**
     * Default constructor
     */
    public VirtualLot() {
        super();
    }

    /**
     * @return the id
     */
    @Id
    @Column(name = "VLT_ID", nullable = false)
    public Long getId() {
        return id;
    }


    /**
     * @return the files
     */
    @ManyToMany
    @JoinTable(name = "R001_FIL_VLT", joinColumns = @JoinColumn(name = "VLT_ID", referencedColumnName = "VLT_ID"), inverseJoinColumns = @JoinColumn(name = "INO_ID", referencedColumnName = "INO_ID"))
    public Collection<VirtualFile> getFiles() {
        return files;
    }
    //[...]
}

ここでは、Spring Data JPA リポジトリを使用して、特定の VirtualLot に含まれる VirtualFiles のサイズを合計しますVirtualLotRepository。クエリは次のように定義されます。

public interface VirtualLotRepository extends JpaRepository<VirtualLot, Long>
{
    @Query("select sum(f.size) from VirtualLot l join l.files f where l.id = ?1")
    long sumFilesSize(long lotId);
}

私の問題は、Hibernate/JPA が「size」キーワードをいじり、それSIZEを hibernate によって定義された関数として解釈することです ( http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html/ch11 .html#ql-コレクション式)

結果のクエリは次のとおりです。

   select
        sum((select
            count(virtualfil2_.VLT_ID) 
        from
            R001_FIL_VLT files1_,
            FIL_FILE virtualfil2_ 
        inner join
            INO_INODE virtualfil2_1_ 
                on virtualfil2_.INO_ID=virtualfil2_1_.INO_ID 
        where
            virtuallot0_.VLT_ID=files1_.VLT_ID 
            and files1_.INO_ID=virtualfil2_.INO_ID)) as col_0_0_ 
    from
        VLT_VIRTUAL_LOT virtuallot0_ 
    inner join
        R001_FIL_VLT files1_ 
            on virtuallot0_.VLT_ID=files1_.VLT_ID 
    inner join
        FIL_FILE virtualfil2_ 
            on files1_.INO_ID=virtualfil2_.INO_ID 
    inner join
        INO_INODE virtualfil2_1_ 
            on virtualfil2_.INO_ID=virtualfil2_1_.INO_ID 
    where
        virtuallot0_.VLT_ID=?

これは(明らかに)機能しません。私はそれをしたい:

   select
        sum(virtualfil2_1_.INO_SIZE)
    from
        VLT_VIRTUAL_LOT virtuallot0_ 
    inner join
        R001_FIL_VLT files1_ 
            on virtuallot0_.VLT_ID=files1_.VLT_ID 
    inner join
        FIL_FILE virtualfil2_ 
            on files1_.INO_ID=virtualfil2_.INO_ID 
    inner join
        INO_INODE virtualfil2_1_ 
            on virtualfil2_.INO_ID=virtualfil2_1_.INO_ID 
    where
        virtuallot0_.VLT_ID=?

これは私の SQL スクラッチパッドで機能します (適切な '?' 値を使用)。

サイズが SIZE 関数ではなく、VirtualInode/VirtualFile エンティティのサイズ プロパティであることを Hibernate/JPA に伝えることは可能ですか?

私はすでに二重引用符のエスケープを試みましたが、うまくいきません。私は Oracle10g 方言を使用しています。

編集:fsizeエンティティに重複したプロパティを 追加VirtualInodeしてリクエストで使用すると、機能しますが、探しているソリューションではありません。

VirtualInode.java

@Column(name = "INO_SIZE", nullable = false, updatable = false, insertable = false)
public long getFsize() {
    return getSize();
}

public void setFsize(final long size) {
    setSize(size);
}

VirtualLotRepository.java

@Query("select sum(f.fsize) from VirtualLot l join l.files f where l.id = ?1")
long sumFilesSize(long lotId);
4

2 に答える 2

1

この解決策についてはよくわかりませんが、試してみてください:

@Query次を使用して変更するだけです。

@Query(value = "select sum(f.size) from VirtualLot l join l.files f where l.id = ?1", nativeQuery = true)

パラメータは、nativeQueryクエリを Oracle ネイティブ クエリに変更することになっています。

このstackoverflowのトピックとそこにあるリンクを参照してください。

これで問題が解決することを願っています。

于 2013-10-14T13:40:49.227 に答える