【问题标题】:How to associate a parent table with two unrelated Child tables如何将父表与两个不相关的子表关联
【发布时间】:2015-04-15 23:21:53
【问题描述】:

我想根据item_type 值将order 表与不同的项目表(bookfood)连接起来。如果item_type 为0,则item_id 应该来自book 表。如果item_type 为1,则item_id 应该来自food 表。

以下是示例表。我希望他们能帮助你理解我的问题。

create table order{
  id int(11) unsigned NOT NULL AUTO_INCREMENT,
  item_type int,
  item_id int
}

create table book{
  id int(11) unsigned NOT NULL AUTO_INCREMENT,
  desc varchar(100)
}

create table food{
  id int(11) unsigned NOT NULL AUTO_INCREMENT,
  field1 varchar(100)
}

我尝试过使用@wherejointable 注释。

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_id",insert="false" update="false")
@WhereJoinTable(clause = "item_type=0")
public Book getBook() {

}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_id",insert="false" update="false")
@WhereJoinTable(clause = "item_type=1")
public Food getFood() {

}

但是,我收到以下错误:

Repeated column in mapping for entity: column: item_id (should be mapped with insert="false" update="false")

这可以在hibernate中实现吗?

【问题讨论】:

  • 我不知道您对order 表的用途,但我想将order 分成两个表BookOrderFoodOrder 比尝试根据行的“类型”有选择地加入不同的表。
  • 您是否可以更改字段或将一些表添加到您的数据库中?如果是,那么最好有一个包含食物和书籍通用字段的基表,然后将订单表连接到这个新表,即“项目”。如果修改架构不是一个选项,让我们看看什么是最好的......

标签: java sql hibernate orm hibernate-mapping


【解决方案1】:

您需要对不可继承的连接使用@Any 注解:

@Any(metaColumn = @Column(name = "ITEM_TYPE"))
@AnyMetaDef(idType = "int", metaType = "int", 
        metaValues = { 
         @MetaValue(targetEntity = Book.class, value = "0"),
         @MetaValue(targetEntity = Food.class, value = "1")
   })
@JoinColumn(name="ITEM_ID")
private Object item;

所以item 可以加载为BookFood

【讨论】:

  • 谢谢,应该是正确答案。通过搜索“任何”注释来理解您的答案。我发现了问题stackoverflow.com/questions/217831/…。 “any”的使用将解决我的问题。
【解决方案2】:

我有另一个解决方案来解决这个问题,即对订单表使用继承。在您的问题中,您必须放置两种类型的订单和面向对象的方法,这些类型是 BookOrder 和 FoodOrder,它们通过使用单表继承策略共享同一个表。

书课。

@Entity
public class Book {

    @Id
    @GeneratedValue
    private int    id;

    private String description;
} 

食品类

@Entity
public class Food {
    @Id
    @GeneratedValue
    private int    id;

    private String field1;
}

让我们创建一个抽象的订单类

@MappedSuperclass
public abstract class Order {

    @Id
    @GeneratedValue
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

}

现在我们为这个 Order 表创建两个子类,并且我们使用单表继承,所以我们需要提供区分列(这是 hibernate 映射到对象的列),我们将其定义为“item_type”列.

书单

@Entity
@Table(name = "orders")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "item_type", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue(value = "0")
public class BookOrder extends Order {

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "item_id")
    private Book book;

}

现在我们有了 FoodOrder 表,它再次扩展了 Order 表

@Entity
@Table(name = "orders")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "item_type", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("1")
@Data
public class FoodOrder extends Order {

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "item_id")
    private Food food;

}

上述映射完全符合您的要求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-24
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多