2012-07-19 20 views
0

我在数据库模式中遇到了两个表的hibernate映射问题。一个叫BINARY_DATA_CONTENTS,另一个叫BINARY_DATABINARY_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偷懒装,只有当需要这种耐心(通过getDataBinaryData)。我不知道,我有我的所有注释的设置正确,因为我得到试图挽救一个新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,它会对它做各种奇怪的事情。这可能是由于...

回答

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; 
+0

下面没有什么与'AUTHORISATION_REQUEST_ID' ...这是冬眠的东西是无懈可击的东西。我本来有一个'@ OneToOne',但遇到了类似的错误,所以我尝试了@ @ OneToMany'的黑客集合。查看我编辑的问题,查看我使用@ @ OneToOne获得的错误。 'BinaryData'只能引用一个'BinaryDataContents',所以'@ oneToOne'应该没问题。 – 2012-07-19 17:54:27

+0

您可能会将另一个具有OneToMany关联的实体与具有名为AUTHORIZATION_REQUEST_ID的JoinColumn的BinaryData关联起来。 – 2012-07-19 18:01:13

+0

实际上,这个巨型企业级应用程序在幕后做了一些可怕的事情(参见上面的更新2)。在任何引用BinaryData的实体中没有'AUTHORISATION_REQUEST_ID'。 – 2012-07-19 18:14:51