20

私が使用している古いテーブルがあります。これは次のようになります。

+------------------+--------------+------+-----+---------+-------+
| Field            | Type         | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+-------+
| BINARY_DATA_ID   | varchar(255) | NO   | PRI |         |       |
| BINARY_DATA      | longblob     | YES  |     | NULL    |       |
| BINARY_DATA_NAME | varchar(255) | YES  |     | NULL    |       |
+------------------+--------------+------+-----+---------+-------+

BinaryDataこれに関する主な問題はBINARY_DATABINARY_DATA_NAME. これを設計する最善の方法は、データをメタデータ (ファイル名など) から分割して、別々のテーブルに配置することです。そこから、データを遅延ロードするのは簡単です。これは、最初に行うべき方法です。

残念ながら、組織の制約により、上記を行うことができない場合があります。回避策として、別のテーブルに分割する代わりに、いくつかの注釈を使用してその列を遅延ロードすることは可能ですか? BinaryData内部静的BinaryDataDataクラスが@Embeddedあり、属性が@Basic(fetch=FetchType.LAZY)次のようになるように、クラスを変更しました。

@Entity
@Table
@Proxy(lazy=false)
@Inheritance(strategy=InheritanceType.JOINED)
public class BinaryData implements Serializable, Persistable<BinaryData>, Cloneable {

    private static final long serialVersionUID = /** blah */;

    @Id @Column @GeneratedValue(generator="uuid") @GenericGenerator(name="uuid", strategy="uuid")
    private String id;

    @Column
    private String binaryDataName;

    @Embedded
    @Basic(fetch = FetchType.LAZY)
    private BinaryDataData binaryData;

    @Transient
    private String cacheId;

    /**
     * Hibernate constructor
     */
    public BinaryData() { /* Creates a new instance of Attachment. */}

    public BinaryData(byte[] binaryData, String binaryDataName) {
        this.binaryData = new BinaryDataData(ArrayUtils.clone(binaryData));
        this.binaryDataName = binaryDataName;
    }

    /**
     * Returns the BinaryData byte stream.
     *
     * @return binaryData byte stream
     */
    @Embedded
    @Basic(fetch = FetchType.LAZY)
    public byte[] getBinaryData() {
        if (this.binaryData == null) {
            return new byte[0];
        }
        return binaryData.getActualData();
    }

    @Embeddable
    public static class BinaryDataData implements Serializable {
        @Column(length=32*1024*1024, columnDefinition="longblob", name="BINARY_DATA") @Lob
        private byte[] actualData;

        public BinaryDataData() { }

        public BinaryDataData(byte[] data) {
            this.actualData = data;
        }

        public byte[] getActualData() {
            if (this.actualData == null) {
                return new byte[0];
            }
            return this.actualData;
        }

        public void setBinaryData(byte[] newData) {
            this.actualData = newData;
        }

        @Override public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (!(obj instanceof BinaryDataData)) {
                return false;
            }
            final BinaryDataData other = (BinaryDataData) obj;
            if (!Arrays.equals(actualData, other.actualData)) {
                return false;
            }
            return true;
        }
    }

    /** onwards... */

残念ながら、これは機能しません。私が見ている SQL は、バイナリ データが要求されていない場合でも、オブジェクトの完全なフェッチを示しています。

select ideaattach0_.BINARY_DATA_ID as BINARY1_9_, ideaattach0_1_.BINARY_DATA as BINARY2_9_, ideaattach0_1_.BINARY_DATA_NAME as BINARY3_9_, ideaattach0_.IDEA_BUCKET_ID as IDEA2_136_ from IDEA_ATTACHMENT ideaattach0_ inner join BINARY_DATA ideaattach0_1_ on ideaattach0_.BINARY_DATA_ID=ideaattach0_1_.BINARY_DATA_ID where ideaattach0_.BINARY_DATA_ID=?

何か案は?ありがとうございました。

4

3 に答える 3

14

Hibernate の第 19 章から。パフォーマンスの向上:

遅延属性フェッチ: インスタンス変数がアクセスされると、属性または単一値の関連付けがフェッチされます。このアプローチには、ビルド時のバイトコード インストルメンテーションが必要ですが、ほとんど必要ありません。

于 2012-07-17T16:00:29.370 に答える
0

この問い合わせの日付は知っていますが、列のサブセットとしてマップする射影値クラスを使用し、その射影値オブジェクトをインスタンス化する指定された名前付きクエリでその射影を使用しようとしました。ここで参照されている基本オブジェクト。

この方法を使用するソリューションに取り組んでいるため、現在完全な例はありません。ただし、基本的な考え方は、フィールドが「Projection_Object_Target」のコンストラクター内で直接参照される「select NEW Projection_Object_Target」構文を使用する JPA クエリを作成することです。

IE 次のようにコンストラクター式を使用します。

SELECT NEW fully.qualified.package.name.ProjectionObject(baseObject.column_target_0,baseObject.column_target_1,...,baseObject.column_target_n) FROM BaseObjectMappedInDBTable AS baseObject

一般的な使用例:

String queryStr =
  "SELECT NEW fully.qualified.package.name.ProjectionObject(baseObject.column_target_0) " +
  "FROM BaseObjectMappedInTable AS baseObject";
TypedQuery<ProjectionObject> query =
  em.createQuery(queryStr, ProjectionObject.class);
List<ProjectionObject> results = query.getResultList();
于 2016-03-13T00:56:11.217 に答える