我在网上搜索我的问题,但没有找到任何有用的东西(或者至少我没有搜索好?♂️) 问题是:我的意图是允许不同的猫有相同的玩具关系(猫id可以有不同猫id的相同玩具id)与我的代码在db中的重复是不允许的。添加mysql工作台屏幕截图以容纳问题(对不起,我的英语不好)
我使用jpa来完成这个任务。我做错了什么?
mysql工作台截图
cat类
@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)显式地将toys添加到数据库中时,我才能使代码按预期工作。t3)并删除@manytomany注解中的cascade选项。
下面的代码
@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:传递给persist的分离实体。
我的意图是不保存玩具手动,我希望他们被添加到数据库与猫豆一起。
你知道为什么cascade不起作用吗?
2条答案
按热度按时间k2fxgqgv1#
你可以这样使用一对多的关系。
在玩具课上,你可以这样做。
hiz5n14c2#
仔细检查。
@OneToMany
这意味着一只猫可以有很多玩具。但是@OneToMany
即使您不使用它并使其单向,它也会与另一侧的另一个注解同时出现。那个注解是@ManyToOne
. 所以如果你有双向的话。这意味着多个玩具只与一只猫有关。你知道我要去哪里。这种关系不允许同一个玩具在多只猫。一只猫有很多玩具!
所以你想要的解决办法是
@ManyToMany
```public class Cat {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
public class Toy {
@ManyToMany
private List cat;
}