gpt4 book ai didi

java - 如何建立基于非关键字段的关系?

转载 作者:IT老高 更新时间:2023-10-28 20:47:24 26 4
gpt4 key购买 nike

我有以下两个实体,当我尝试将项目添加到我的汽车表时,它会显示以下错误消息;因此,它不允许我拥有多于一辆带“自动”传输的汽车。

错误:

 #1062 - Duplicate entry 'Auto' for key 'UK_bca5dfkfd4fjdhfh4ddirfhdhesr' 

实体:

汽车

@Entity
public class Car implements java.io.Serializable {


@Id
@GeneratedValue
long id;
@Column(name="transmission", nullable = false)
String transmission;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "car")
Set<CarFactory> factories;
...
}

汽车表的示例值:

10 Auto
12 Auto
43 Manual
54 Manual
65 Normal
68 Standard
90 Normal
99 NoGear

汽车工厂

@Entity
public class CarFactory implements java.io.Serializable {

@Id
@JoinColumn(name="transmission",referencedColumnName = "transmission")
@ManyToOne
Car car;

@Id
@JoinColumn(name="factory_id", referencedColumnName= "id")
@ManyToOne
Factory factory;

...
}

CarFactory 表的预期值

Auto Fac1
Auto Fac2
Manual Fac1
Auto Fac5
Standard Fac6
Normal Fac3
NoGear Fac1

我已关注此 question 的答案也一样,但是没有用。

长话短说,我需要一个表,其中包含来自其他表的两个外键,以及组合的主键。它不应该强制参与表中的唯一外键。

最佳答案

我模拟了您的用例,您可以在 GitHub 上找到测试。 .

这些是映射:

@Entity(name = "Car")
public static class Car implements Serializable {

@Id
@GeneratedValue
long id;

@Column(name="transmission", nullable = false)
String transmission;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "car")
Set<CarFactory> factories;
}

@Entity(name = "Factory")
public static class Factory implements Serializable {

@Id
@GeneratedValue
long id;
}

@Entity(name = "CarFactory")
public static class CarFactory implements Serializable {

@Id
@ManyToOne
@JoinColumn(name = "transmission", referencedColumnName = "transmission")
Car car;

@ManyToOne
@Id
Factory factory;

public void setCar(Car car) {
this.car = car;
}

public void setFactory(Factory factory) {
this.factory = factory;
}
}

这是添加一些测试数据的方式:

doInTransaction(session -> {
Car car = new Car();
car.transmission = "Auto";

Car car1 = new Car();
car1.transmission = "Manual";

Factory factory = new Factory();
session.persist(factory);
session.persist(car);
session.persist(car1);

CarFactory carFactory = new CarFactory();
carFactory.setCar(car);
carFactory.setFactory(factory);

CarFactory carFactory1 = new CarFactory();
carFactory1.setCar(car1);
carFactory1.setFactory(factory);

session.persist(carFactory);
session.persist(carFactory1);
});

并且测试工作正常:

@Test
public void test() {
doInTransaction(session -> {
List<CarFactory> carFactoryList = session.createQuery("from CarFactory").list();
assertEquals(2, carFactoryList.size());
});
}

更新

由于以下唯一约束,您会遇到异常:

alter table Car add constraint UK_iufgc8so6uw3pnyih5s6lawiv  unique (transmission)

这是正常行为,因为 FK 必须唯一标识 PK 行。就像您不能有更多具有相同 PK 的行一样,您的 FK 标识符引用也不能超过一行。

您的映射是问题所在。您需要引用其他内容,而不是 transmision。您需要一个唯一的汽车标识符,例如 VIN(车辆识别号),因此您的映射变为:

@Entity(name = "Car")
public static class Car implements Serializable {

@Id
@GeneratedValue
long id;

@Column(name="vin", nullable = false)
String vin;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "car")
Set<CarFactory> factories;
}

@Entity(name = "CarFactory")
public static class CarFactory implements Serializable {

@Id
@ManyToOne
@JoinColumn(name = "vin", referencedColumnName = "vin")
Car car;

@ManyToOne
@Id
Factory factory;

public void setCar(Car car) {
this.car = car;
}

public void setFactory(Factory factory) {
this.factory = factory;
}
}

这样,vin 是唯一的,并且 Child 关联可以引用 唯一 一个父级。

关于java - 如何建立基于非关键字段的关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29998660/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com