Hibernate:'实体'中的重复列映射'不允许在属性中混合可更新和不可更新的列'

时间:2013-08-15 16:20:36

标签: java hibernate jpa orm mapping

我有遗留数据库。

+----+  +------------+ +------------+
|Site|  |Content     | |Program     |
+----+  +------------+ +------------+
|id  |  |id:PK       | |siteId:PK,FK|
|name|  |siteId:FK   | |code:PK     |
+----+  |prog_code:FK| |name        |
        |prog_param  | +------------+
        +------------+  

表内容有一个PK列。 siteId列不是PK的一部分。 表程序有两个PK列(siteId,代码)。它是复合PK。此表用作模板。只有program中的变量才是参数,它位于表Content的prog_param列中。

我想将此表映射到这样的对象。

+-----------+  +------------+  +-----------+  +---------------+
|Site       |  |Program     |  |ProgramId  |  |Content        |
+-----------+  +------------+  +-----------+  +---------------+
|id:long    |  |id:ProgramId|  |site:Site  |  |id:long        |
|name:String|  |name:String |  |code:String|  |site:Site      |
+-----------+  |param:String|  +-----------+  |program:Program|
               +------------+                 +---------------+

但我不知道在这种复杂的情况下如何映射'内容'和'程序'。

所以,我试图让情况变得简单。 我已将prog_param映射到Content

+-----------+  +------------+  +-----------+  +-------------------+
|Site       |  |Program     |  |ProgramId  |  |Content            |
+-----------+  +------------+  +-----------+  +-------------------+
|id:long    |  |id:ProgramId|  |site:Site  |  |id:long            |
|name:String|  |name:String |  |code:String|  |site:Site          |
+-----------+  +------------+  +-----------+  |program:Program    |
                                              |programParam:String|
                                              +-------------------+

代码

@Entity
@Table(name = "SITE")
@Getter @Setter
public class Site {
    @Id
    @Column(name = "SITE")
    protected String id;

    @Column(name = "NAME")
    protected String name;
}


@Entity
@Table(name = "PROGRAM")
@Getter @Setter
public class Program {
    @EmbeddedId
    protected ProgramId id;
    @Column(name = "NAME")
    protected String name;
}

@Embeddable
@Getter @Setter @EqualsAndHashCode
public class ProgramId implements Serializable{
    @ManyToOne
    @JoinColumn(name = "SITE")
    protected Site site;

    @Column(name = "code")
    protected String code;
}

@Entity
@Table(name="CONTENT")
@Getter
@Setter
public class Content {
    @Id
    @Column(name = "ID")
    protected Long id;

    @ManyToOne
    @JoinColumn(name = "SITEID",referencedColumnName="SITE")
    protected Site site;


    @OneToOne
    @JoinColumns({
        @JoinColumn(name="SITEID",referencedColumnName="SITE"),
        @JoinColumn(name="PROG_CODE",referencedColumnName="CODE"), 
    })
    protected Program program;
}

但这不起作用。 Hibernate抛出'实体映射中的重复列'异常。

所以我研究了一些解决方案。 最后,我发现这个'实体映射中的重复列'在Hibernated无法确定使用哪个属性时抛出异常。

Stackoverflows的解决方案是将'insertable = false,updatable = false'设置为@JoinColumn,因此让hibernate可以确定使用哪个属性。

我想使用Content的属性'site',因为它经常被使用。 Site和Program属性在我的应用程序中单独使用。

所以我尝试将'insertable = false,updatable = false'设置为Content的属性'program'

    @OneToOne
    @JoinColumns({
        @JoinColumn(name="SITEID",referencedColumnName="SITE", insertable=false, updatable=false),
        @JoinColumn(name="PROG_CODE",referencedColumnName="CODE"), 
    })
    protected Program program;

这也不行。 '不允许在属性中混合可更新列和不可更新列'抛出异常。

所以我将'insertable = false,updatable = false'设置为'PROG_CODE',当然,当我设置不同的prog_code时,Hibernate不会更改PROG_CODE。

此时,我不知道。

请让我知道解决这种情况的一些想法。

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,共享属性的两个复合键失败,“实体映射中的重复列”。我认为这可能是一个错误,参考:https://hibernate.atlassian.net/browse/HHH-4582。我正在使用Hibernate 3.6.4