0

DB スキーマ内の 2 つのテーブルの休止状態のマッピングに問題があります。1 つは呼び出されBINARY_DATA_CONTENTS、もう 1 つは ですBINARY_DATABINARY_DATAには名前フィールドと へのポインタしかありませんBINARY_DATA_CONTENTS。スキーマは次のようになります。

BINARY_DATA_CONTENTS:

CREATE TABLE `BINARY_DATA_CONTENTS` (
  `BINARY_DATA_CONTENTS_ID` varchar(255) NOT NULL,
  `BINARY_DATA` longblob, -- stores the data
  PRIMARY KEY (`BINARY_DATA_CONTENTS_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

BINARY_DATA:

CREATE TABLE `BINARY_DATA` (
  `BINARY_DATA_ID` varchar(255) NOT NULL DEFAULT '',
  `BINARY_DATA_NAME` varchar(255) DEFAULT NULL, -- just a filename
  `BINARY_DATA_CONTENTS_ID` varchar(255) DEFAULT NULL, -- points to BINARY_DATA_CONTENTS
  PRIMARY KEY (`BINARY_DATA_ID`),
  KEY `BINARY_DATA_CONTENTS_FK` (`BINARY_DATA_CONTENTS_ID`),
  CONSTRAINT `BINARY_DATA_CONTENTS_FK` FOREIGN KEY (`BINARY_DATA_CONTENTS_ID`) REFERENCES `BINARY_DATA_CONTENTS` (`BINARY_DATA_CONTENTS_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

これらのテーブルごとに Java クラスがあります。

BinaryDataContents:

@Entity
@Table(name="BINARY_DATA_CONTENTS")
@Proxy(lazy=true)
@Inheritance(strategy= InheritanceType.JOINED)
public class BinaryDataContents implements Serializable, Persistable<BinaryDataContents>, Cloneable {
    private static final long serialVersionUID = /** blah */;

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

    @Column(name="BINARY_DATA", length=32*1024*1024, columnDefinition="longblob") @Lob
    private byte[] contents;

    /**
     * Hibernate constructor
     */
    public BinaryDataContents() { }

    public BinaryDataContents(byte[] contents) {
        this.contents = ArrayUtils.clone(contents);
    }

    public byte[] getContents() {
        return contents;
    }
    // etc...

バイナリデータ:

@Entity
@Table(name="BINARY_DATA")
@Inheritance(strategy=InheritanceType.JOINED)
public class BinaryData implements Serializable, Persistable<BinaryData>, Cloneable {

    private static final long serialVersionUID = 2154854247822039938L;

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

    @Column
    private String binaryDataName;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name="BINARY_DATA_CONTENTS_ID", nullable=true) @ForeignKey(name="BINARY_DATA_CONTENTS_FK")
    private Collection<BinaryDataContents> binaryDataContents;

    @Transient
    private String cacheId;

    /**
     * Hibernate constructor
     */
    public BinaryData() { this.binaryDataContents = Sets.newHashSet(new BinaryDataContents()); }

    /**
     * Create a new instance of BinaryData.
     *
     * @param binaryDataData <code>byte []</code> of the file to store.
     * @param binaryDataName Name of attachment
     */
    public BinaryData(byte[] binaryDataData, String binaryDataName) {
        this.binaryDataContents = Sets.newHashSet(new BinaryDataContents(ArrayUtils.clone(binaryDataData)));
        this.binaryDataName = binaryDataName;
    }

    /**
     * Returns the BinaryData byte stream.
     *
     * @return binaryDataContents byte stream
     */
    public byte[] getData() {
        return binaryDataContents.iterator().next().getContents();
    }

    /**
     * Returns the BinaryData name.
     *
     * @return BinaryData name
     */
    public String getBinaryDataName() {
        return binaryDataName;
    }
    // etc...

BinaryDataContents必要なときだけ ( in 経由getDataで) 遅延ロードしたいと思いBinaryDataます。BinaryData新しいオブジェクトを保存しようとするとエラーが発生するため、すべての注釈が正しく設定されているかどうかわかりません。

PersistenceException: Failed to commit Caused by: org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update Caused by: java.sql.BatchUpdateException: Unknown column 'AUTHORISATION_REQUEST_ID' in 'field list'

AUTHORISATION_REQUEST_IDこれらのテーブルまたはクラスで呼び出される列またはフィールドがどこにもないため、これは奇妙です。休止状態が混乱し、奇妙な列名を SQL にスローしているようです。

insert into BINARY_DATA (BINARY_DATA_NAME, AUTHORISATION_REQUEST_ID) values (?, ?)

これを引き起こしている可能性のあるものについてのアイデアはありますか? ありがとうございました。

更新 1

注釈を使用する@OneToOneと、エラーがわずかに変化します。挿入はBINARY_DATA_CONTENTS正しい SQL を生成するように見えます。

insert into BINARY_DATA_CONTENTS (BINARY_DATA, BINARY_DATA_CONTENTS_ID) values (?, ?)

ただし、BINARY_DATA挿入にはまだランダムな列名が含まれています。

insert into BINARY_DATA (BINARY_DATA_CONTENTS_ID, BINARY_DATA_NAME, AUTHORISATION_REQUEST_ID) values (?, ?, ?)

更新 2

AUTHORISATION_REQUEST_IDどこからともなく表示されるstage列は、休止状態の注釈付きクラスをすべてアプリケーションに登録する順序に基づいて変更されます (場合によってはDATABASE_UPGRADE_ID)。アプリケーションはこれらのクラスのリストを保持し、それらをある種の非常識な PersistenceConfiguration に渡します。PersistenceConfiguration はそれを使ってあらゆる種類の奇妙なことを行います。それが原因なのかな…

4

1 に答える 1

0

この AUTHORIZATION_REQUEST_ID がどこから来たのかわかりません。おそらくあなたが私たちに見せていない何かから。しかし、あなたのマッピングは明らかに間違っています。バイナリ データには、バイナリ データの内容に対する外部キーがあります。

したがって、これは、バイナリ データが 1 つのバイナリ データ コンテンツしか持てないことを意味します。そのため、複数のバイナリ データが同じ内容を共有する可能性がある場合は、ManyToOne を使用する必要があります。それ以外の場合は、OneToOne が必要です。もちろん、OneToMany はあなたが望むものではありません。Set を使用し、その最初の要素だけに関心があるという事実は、それが間違っていることを強く示しています。それがどうあるべきかは次のとおりです。

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "BINARY_DATA_CONTENTS_ID", nullable=true) 
@ForeignKey(name = "BINARY_DATA_CONTENTS_FK")
private BinaryDataContents binaryDataContents;
于 2012-07-19T17:47:36.423 に答える