这个想法很简单:我想创建一个 ManyToMany 依赖项,但有一个额外的列。
在我的项目中,我使用Project Lombok,因此@Data取代了我Getter/Setter/ToString/Equals/Hash.
我的想法 100% 类似于:https ://vladmihalcea.com/the-best-way-to-map-a-many-to-many-association-with-extra-columns-when-using-jpa-and- hibernate/ 但是,这个选项对我不起作用
实体关系图:
测试程序时出现错误:
Caused by: java.sql.SQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails
(`dishdatabase`.`dish_size`, CONSTRAINT `FKqpfda2uojtpf1u243dy0e55fq` FOREIGN KEY (`product_id`) REFERENCES `product` (`id`))
更新 1(2020 年 4 月 25 日):
项目已移至github:https
://github.com/Antonio112009/Many-To-Many_with_extra_column
底部错误已解决,但出现另一个:我可以将一个对象连接到另一个对象,但无法连接相同的多个对象互相打字。问题和错误在github上进行了描述。
org.springframework.orm.jpa.JpaSystemException: Could not set field value [SHORT_CIRCUIT_INDICATOR] value by reflection : [class com.antonio112009.manyToMany.entity.PostTagId.tagId]
setter of com.antonio112009.manyToMany.entity.PostTagId.tagId; nested exception is org.hibernate.PropertyAccessException: Could not set field value [SHORT_CIRCUIT_INDICATOR]
value by reflection : [class com.antonio112009.manyToMany.entity.PostTagId.tagId] setter of com.antonio112009.manyToMany.entity.PostTagId.tagId
下面是我试图在我的项目中实现的代码:
产品.java:
@Entity
@Data
@Table
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "product_generator")
@SequenceGenerator(name="product_generator", sequenceName = "seq_product", allocationSize = 1)
private Long id;
@Column
private String name;
@OneToMany(
mappedBy = "product",
cascade = CascadeType.ALL,
orphanRemoval = true
)
List<DishSize> dishSizes = new ArrayList<>();
public void addDishSize(DishSize dishSize) {
dishSizes.add(dishSize);
dishSize.setProduct(this);
}
public void removeDishSize(DishSize dishSize) {
dishSizes.remove(dishSize);
dishSize.setProduct(null);
}
}
DishSize.java
@Entity
@Data
@Table
public class DishSize implements Serializable {
@Id
@GeneratedValue
private Long id;
private Integer size;
@ManyToOne(fetch = FetchType.LAZY)
private Product product;
@ManyToOne(fetch = FetchType.LAZY)
private Dish dish;
}
菜.java
@Entity
@Data
@Table
public class Dish {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "dish_generator")
@SequenceGenerator(name="dish_generator", sequenceName = "seq_dish", allocationSize = 1)
private Long id;
@Column
private String name;
@OneToMany(
mappedBy = "dish",
cascade = CascadeType.ALL,
orphanRemoval = true
)
List<DishSize> dishSizes = new ArrayList<>();
public void addDishSize(DishSize dishSize) {
dishSizes.add(dishSize);
dishSize.setDish(this);
}
public void removeDishSize(DishSize dishSize) {
dishSizes.remove(dishSize);
dishSize.setDish(null);
}
测试我的程序是否失败:
DishRepositoryTest.java
@SpringBootTest
class DishRepositoryTest {
@Autowired
private DishRepository dishRepository;
@Autowired
private ProductRepository productRepository;
private String name = "Цезарь";
@BeforeEach
void setUp() {
productRepository.deleteAll();
dishRepository.deleteAll();
Dish dish = new Dish();
dish.setName(name);
dish.setNotes("тест");
dishRepository.save(dish);
}
@Test
@Transactional
void deleteProductButNotDish(){
String nameProduct = "яблоко";
Integer size = 250;
Product product = new Product();
product.setName(nameProduct);
productRepository.save(product);
product = productRepository.findByNameAndSort(nameProduct, null);
Dish dish = dishRepository.findByName(name);
DishSize dishSize = new DishSize();
dishSize.setDish(dish);
dishSize.setSize(size);
product.addDishSize(dishSize);
dish.addDishSize(dishSize);
dishRepository.save(dish);
//Test
product = productRepository.findByNameAndSort(nameProduct, null);
product.getDishSizes().get(0).getDish().removeDishSize(product.getDishSizes().get(0));
productRepository.save(product);
productRepository.deleteByNameAndSort(nameProduct, null);
dish = dishRepository.findByName(name);
assertNotNull(dish, "checking if dish is not deleted");
assertNull(productRepository.findByNameAndSort(nameProduct, null), "checking if product is deleted");
assertEquals(0, dish.getDishSizes().size(), "checking if dishSize is deleted");
}
}

Github 上的示例
@ManyToMany c дополнительной колонкой可以在这里找到一个工作示例当前,删除其中嵌套了一个或多个对象的对象存在问题。
更新 1
删除多个对象的问题几乎解决了。剩下的就是添加对象的级联删除。
主要要求:
@Data龙目岛。问题出在@EqualsAndHashCode. 可以在此问题中找到有关此事物的来源的链接equals,addTag/Post,removeTag/Post的写法应与以下示例相同。没有它们,就不可能连接两个实体。正确的代码输入
菜.java
DishSize.java
DishSizePK.java
产品