【发布时间】:2021-07-07 15:59:04
【问题描述】:
我在互联网上搜索了我的问题,但没有找到任何有用的东西(或者至少我没有很好地搜索????♂️) 问题是:我打算让不同的猫有相同的玩具关系(cat_id 可以有不同 cat_id 的相同 toy_id) 不允许在数据库中使用我的代码重复。 添加了 MySQL 工作台屏幕截图以适应问题。 (对不起我的英语不好)
我正在使用 JPA 来完成这项任务。 我做错了什么?
猫类
@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "cats")
public class Cat {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private float weight;
private String color;
@OneToMany(cascade = CascadeType.ALL)
@Singular
private List<Toy> toys;
}
玩具抽象类
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "toys")
public abstract class Toy {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected int id;
protected String name;
}
特定玩具类
@Entity
public class Ball extends Toy {
public Ball() {
super();
name = "Ball";
}
}
测试类
@Component
@RequiredArgsConstructor
@Order(1)
public class TestCatService implements CommandLineRunner {
private final CatService service;
@Override
public void run(String... args) throws Exception {
Toy t1 = new Ball();
Toy t2 = new RubberBand();
Toy t3 = new Mouse();
Toy t4 = new Ball();
//////////////////////////////////////////////////////////////////////
TestUtils.printTestInfo("Add Pink Cat");
Cat pinkCat = Cat.builder().color("Pink")
.name("Mitzi")
.weight(4.3f)
.toy(t1)
.toy(t3)
.build();
try {
service.addCat(pinkCat);
System.out.println("Cat added to DB");
} catch (Exception e) {
System.out.println(e.getMessage());
}
//////////////////////////////////////////////////////////////////////
TestUtils.printTestInfo("Add White Cat");
Cat whiteCat = Cat.builder()
.color("White")
.name("Mitzi")
.weight(4.3f)
.toy(t1)
.toy(t2)
.toy(t3)
.build();
try {
service.addCat(whiteCat);
System.out.println("Cat added to DB");
} catch (Exception e) {
System.out.println(e.getMessage());
}
//////////////////////////////////////////////////////////////////////
TestUtils.printTestInfo("Add tricolor Cat");
Cat tricolorCat = Cat.builder()
.color("Tri-color")
.name("shocki")
.weight(2.7f)
.build();
try {
service.addCat(tricolorCat);
System.out.println("Cat added to DB");
} catch (Exception e) {
System.out.println(e.getMessage());
}
TestUtils.printTestInfo("Add Orange Cat");
Cat orange = Cat.builder()
.color("Orange")
.name("jinji")
.toy(t3)
.toy(t4)
.weight(6.2f)
.build();
try {
service.addCat(orange);
System.out.println("Cat added to DB");
} catch (Exception e) {
System.out.println(e.getMessage());
}
//////////////////////////////////////////////////////////////////////
TestUtils.printTestInfo("Update Cat to Pink Color");
whiteCat.setColor("Pink");
try {
service.updateCat(whiteCat);
System.out.println("Cat updated");
} catch (Exception e) {
System.out.println(e.getMessage());
}
//////////////////////////////////////////////////////////////////////
TestUtils.printTestInfo("Update Cat to Black Color");
whiteCat.setColor("Black");
try {
service.updateCat(whiteCat);
System.out.println("Cat updated");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
控制台输出
_______________________________________
Testing "Add Pink Cat"
Pink cats are not allowed
_______________________________________
Testing "Add White Cat"
Cat added to DB
_______________________________________
Testing "Add tricolor Cat"
Cat added to DB
_______________________________________
Testing "Add Orange Cat"
detached entity passed to persist: com.jb.lab4.beans.toys.Toy; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.jb.lab4.beans.toys.Toy
_______________________________________
Testing "Update Cat to Pink Color"
Pink cats are not allowed
_______________________________________
Testing "Update Cat to Black Color"
Cat updated
更新
只有当我使用 toyRepository.saveAll(t1, t2. t3) 将玩具显式添加到数据库并删除 @ManyToMany 注释中的级联选项时,我才设法使代码按预期工作。
代码如下
@Component
@RequiredArgsConstructor
@Order(1)
public class TestCatService implements CommandLineRunner {
private final CatService service;
private final ToyRepository toyRepository;
@Override
public void run(String... args) throws Exception {
Toy t1 = new Ball();
Toy t2 = new RubberBand();
Toy t3 = new Mouse();
Toy t4 = new Ball();
// manually add toys to database
toyRepository.saveAll(Arrays.asList(t1,t2,t3,t4));
//////////////////////////////////////////////////////////////////////
TestUtils.printTestInfo("Add Pink Cat");
Cat pinkCat = Cat.builder().color("Pink")
.name("Mitzi")
.weight(4.3f)
.toy(t1)
.toy(t3)
.build();
try {
service.addCat(pinkCat);
System.out.println("Cat added to DB");
} catch (Exception e) {
System.out.println(e.getMessage());
}
//////////////////////////////////////////////////////////////////////
TestUtils.printTestInfo("Add White Cat");
Cat whiteCat = Cat.builder()
.color("White")
.name("Mitzi")
.weight(4.3f)
.toy(t1)
.toy(t2)
.toy(t3)
.build();
try {
service.addCat(whiteCat);
System.out.println("Cat added to DB");
} catch (Exception e) {
System.out.println(e.getMessage());
}
//////////////////////////////////////////////////////////////////////
TestUtils.printTestInfo("Add tricolor Cat");
Cat tricolorCat = Cat.builder()
.color("Tri-color")
.name("shocki")
.weight(2.7f)
.build();
try {
service.addCat(tricolorCat);
System.out.println("Cat added to DB");
} catch (Exception e) {
System.out.println(e.getMessage());
}
TestUtils.printTestInfo("Add Orange Cat");
Cat orange = Cat.builder()
.color("Orange")
.name("jinji")
.toy(t1)
.toy(t4)
.weight(6.2f)
.build();
try {
service.addCat(orange);
System.out.println("Cat added to DB");
} catch (Exception e) {
System.out.println(e.getMessage());
}
//////////////////////////////////////////////////////////////////////
TestUtils.printTestInfo("Update Cat to Pink Color");
whiteCat.setColor("Pink");
try {
service.updateCat(whiteCat);
System.out.println("Cat updated");
} catch (Exception e) {
System.out.println(e.getMessage());
}
//////////////////////////////////////////////////////////////////////
TestUtils.printTestInfo("Update Cat to Black Color");
whiteCat.setColor("Black");
try {
service.updateCat(whiteCat);
System.out.println("Cat updated");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "cats")
@Primary
public class Cat {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private float weight;
private String color;
// removed the @ManyToMany(cascade = CascadeType.ALL) option
@ManyToMany
@Singular
private List<Toy> toys;
}
现在有了这个变化,多只猫可以像预期的那样拥有多个玩具。
如果我放回 @ManyToMany(cascade = CascadeType.ALL) 代码会中断并出现异常 org.hibernate.PersistentObjectException: detached entity pass to persist。
我的目的不是手动保存玩具,我希望将它们与猫豆一起添加到数据库中。
任何想法为什么它不适用于级联?
【问题讨论】:
-
你想要多对多的关系,对吧?
-
@code_mechanic 如果我做对了。我还尝试用
@ManyToMany替换@OneToMany注释,但得到相同的结果,不允许重复 -
只放注解可能行不通,要多对多工作,您需要从双方定义关系,请检查此how。
-
@code_mechanic 谢谢你的链接????????,我去看看
标签: java mysql spring spring-boot jpa