1

我想在这种情况下创建一个应用程序:Zk 6、Spring v3.1.1、JPA 2.0、Hibernate 4.1.4,都带有注释,但我有一些带有 JPA 概念的 pb。

这是一种案例研究:

3 个表,全部通过连接表链接;我们正在处理基数 0,n。

  • 所以我们有 T_E_USER、T_E_TYPE 和 T_E_AIR。每个表都有一个数字 ID 和一个简单的 VARCHAR 字段。

  • 使用 T_J_USR_TPE_AIR 创建连接表,其中 3 个 ID 由外键引用,形成组合主键。

我正在使用 Hibernate Tools 生成我的实体(JPA 版本)。这就是问题开始的地方......

在每个实体类中,我都有一个带有注释@OneToMany 的类型的属性。

我有一个表示连接的类,它具有复杂类型(另一个类)的 id 属性,并带有用于复合键的注释 EmbeddedId。以及用@ManyToOne 注释表示三个实体的属性。

这是我的问题,因为那是我感到困惑的地方:

  • 我应该在我的实体的注释@ OneToMany 中将哪个设置为“mappedBy”属性?
  • 我是否被迫做一个代表加入的类实体?
  • 级联如何?是否可以在这种情况下使用它来“自动”丰富连接表?或者我应该手动实例化连接的类代表以便自己保存信息?

非常感谢任何可以帮助我的好心人。


谢谢你的回答,但是当另一个说“不”时,一个说“是”,哈哈

这是我白天所做的,但我还没有接受过测试。

在每个实体表中,我添加了一个 @OneToMany 关系,并将 mappedBy 设置为“join”实体中定义的属性:

@OneToMany(fetch = FetchType.LAZY, 
       mappedBy = "aircraft",
       cascade = { CascadeType.REMOVE })
private Set<UserConfig> userConfigs = new HashSet<UserConfig>(0);

...

@OneToMany(fetch = FetchType.LAZY, 
       mappedBy = "userAccount",
       cascade = { CascadeType.REMOVE })
private Set<UserConfig> userConfigs = new HashSet<UserConfig>(0);

...

@OneToMany(fetch = FetchType.LAZY, 
       mappedBy = "referenceType",
       cascade = { CascadeType.REMOVE })
private Set<UserConfig> userConfigs = new HashSet<UserConfig>(0);

我为连接表创建了一个新实体。

@Entity
@Table(name = "T_J_USR_RFT_AIR_URA")
public class UserConfig implements java.io.Serializable {

@EmbeddedId
@AttributeOverrides({
        @AttributeOverride(name = "airId", 
                           column = @Column(name = "URA_AIR_ID", nullable = false)),
        @AttributeOverride(name = "usrId", 
                           column = @Column(name = "URA_USR_ID", nullable = false)),
        @AttributeOverride(name = "rftId", 
                           column = @Column(name = "URA_RFT_ID", nullable = false))
})  
private UserConfigId id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "URA_RFT_ID", nullable = false, insertable = false, updatable = false)   
private ReferenceType referenceType;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "URA_USR_ID", nullable = false, insertable = false, updatable = false)   
private UserAccount userAccount;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "URA_AIR_ID", nullable = false, insertable = false, updatable = false)   
private Aircraft aircraft;

...
getter & setter
}

其中 UserConfigId 是:

@Embeddable
public class UserConfigId implements java.io.Serializable {

@Column(name = "URA_AIR_ID", nullable = false)  
private Integer airId;

@Column(name = "URA_USR_ID", nullable = false)
private Integer usrId;

@Column(name = "URA_RFT_ID", nullable = false)
private Integer rftId;

...
getter & setter
}

您如何看待这种做法?

如果删除连接表的对象以删除连接中关联的所有元素,我只是使用“级联”。

没关系 ?

无论如何,谢谢汤姆,我会分析你的链接。也感谢 JMelnyk。

如果您想展示此案例的最佳实践,欢迎您。

4

2 回答 2

1

三向连接很棘手。我认为您所做的,使用连接表的实体,可能是正确的做法。要回答您的问题:

  1. 您的@OneToMany属性是指映射连接表的实体;它们应该是mappedBy该实体中的适当@ManyToOne属性。
  2. 是的,不幸的是,连接表的实体是执行此操作的最佳方式。
  3. 级联可用于自动将对象添加到数据库中,但不能用于创建对象。您将需要在代码中创建连接实体的实例。
于 2012-08-07T09:16:30.420 回答
0

我应该在我的实体的注释@ OneToMany 中将哪个设置为“mappedBy”属性?

mappedBy属性表示您要加入的属性名称。阅读更多...

例如,AnyEntity持有实体List<Employee>中的(mappedBy)department属性,并且该属性持有关联。Employeedepartment

我是否被迫做一个代表加入的类实体?

不,您没有为连接表提供实体类。

级联如何?是否可以在这种情况下使用它来“自动”丰富连接表?或者我应该手动实例化连接的类代表以便自己保存信息?

是的,可以通过使用所需的级联类型标记关联来丰富实体及其本身的关联。

例如,我们有一个Department持有者List<Employee>,我将 CascadeType.PERSIST 放在员工身上。现在我们用其属性和员工填充部门对象。当我们完成后,我们只坚持部门,它将对员工进行级联操作。

于 2012-08-07T07:58:04.187 回答