我在数据库模式中遇到了两个表的hibernate映射问题。一个叫BINARY_DATA_CONTENTS
,另一个叫BINARY_DATA
。 BINARY_DATA
只有一个名称字段和一个指向BINARY_DATA_CONTENTS
的指针。这是该架构是什么样子:在查询中使用随机未指定列名的Hibernate
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...
BinaryData:
@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
偷懒装,只有当需要这种耐心(通过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
列似乎来自无处变化的基础上为了使我的应用程序注册所有的hibernate注释类(有时候是DATABASE_UPGRADE_ID
)。应用程序保留了这些类的列表,并将它们传递给某种疯狂的PersistenceConfiguration,它会对它做各种奇怪的事情。这可能是由于...
下面没有什么与'AUTHORISATION_REQUEST_ID' ...这是冬眠的东西是无懈可击的东西。我本来有一个'@ OneToOne',但遇到了类似的错误,所以我尝试了@ @ OneToMany'的黑客集合。查看我编辑的问题,查看我使用@ @ OneToOne获得的错误。 'BinaryData'只能引用一个'BinaryDataContents',所以'@ oneToOne'应该没问题。 – 2012-07-19 17:54:27
您可能会将另一个具有OneToMany关联的实体与具有名为AUTHORIZATION_REQUEST_ID的JoinColumn的BinaryData关联起来。 – 2012-07-19 18:01:13
实际上,这个巨型企业级应用程序在幕后做了一些可怕的事情(参见上面的更新2)。在任何引用BinaryData的实体中没有'AUTHORISATION_REQUEST_ID'。 – 2012-07-19 18:14:51