0

我的数据库模式中两个表的休眠映射有问题。一个被称为BINARY_DATA_CONTENTS,另一个是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

二进制数据:

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 类。

二进制数据内容:

@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延迟加载,仅在需要时(通过getDatain 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我在应用程序中注册所有休眠注释类的顺序(有时DATABASE_UPGRADE_ID是 应用程序保留了这些类的列表并将它们传递给某种疯狂的 PersistenceConfiguration,它会用它做各种奇怪的事情。大概就是这个原因吧……

4

1 回答 1

0

不知道这个 AUTHORIZATION_REQUEST_ID 来自哪里。可能是因为你没有向我们展示。但是您的映射显然是错误的。二进制数据具有二进制数据内容的外键。

所以这意味着一个二进制数据可能只有一个二进制数据内容。所以,如果几个二进制数据可能共享相同的内容,你应该有一个 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 回答