繁体   English   中英

合并同一实体的多个表示(休眠)

[英]Multiple representations of the same entity are being merged (Hibernate)

我的数据库中有两个表-Restaurant和RestaurantTable。 它们之间有一个@OneToMany关系(一家餐馆可以有很多桌子)。 我正在尝试向我的餐厅添加一张桌子。 我可以添加第一个表,但是一旦我尝试添加另一个表,就会出现以下错误:

HTTP Status 500 - Request processing failed; nested exception is java.lang.IllegalStateException: Multiple representations of the same entity [RestaurantTable#6] are being merged. Detached: [Table number 6]; Detached: [Table number 5]

这是我的数据库的样子:

DROP TABLE IF EXISTS `restaurant`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `restaurant` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `restaurant_name` TEXT,
  `address` TEXT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

DROP TABLE IF EXISTS `restaurant_table`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `restaurant_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `table_size` int,
  `table_number` int,
  `restaurant_id` int(11),
  PRIMARY KEY (`id`),
  FOREIGN KEY (`restaurant_id`) references `restaurant`(`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

我的Restaurant.java文件:

@Entity
@Table(name="restaurant")
public class Restaurant {

    @Id
    @Column(name="id")
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Long id;

    @Column(name="restaurant_name")
    private String restaurantName;

    @Column(name="address")
    private String address;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name="restaurant_id")
    private List<RestaurantTable> table = new ArrayList<RestaurantTable>();

    // Getters and setters

RestaurantTable.java:

@Entity
@Table(name="restaurant_table")
public class RestaurantTable {

    @Id
    @Column(name="id")
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Long id;

    @Column(name="table_size")
    private int tableSize;

    @Column(name="table_number")
    private int tableNumber;

    @ManyToOne
    @JoinColumn(name="restaurant_id")
    private Restaurant restaurant;

    // Getters and setters

我的RestaurantTableController.java:

@Controller
public class RestaurantTableController {

    @Autowired
    private RestaurantService restaurantService;

    @Autowired
    private RestaurantTableService restaurantTableService;

    @RequestMapping(value="restaurant/table/{id}", method = RequestMethod.GET)
    public String addRestaurantTable(Model model, @PathVariable Long id) {
        model.addAttribute("table", new RestaurantTable());
        return "newTable";
    }

    @RequestMapping(value = "restaurant/table/{id}", method = RequestMethod.POST)
    public String addRestaurantTable(@PathVariable Long id, @ModelAttribute ("table") RestaurantTable table) {
        Restaurant restaurant = restaurantService.getRestaurant(id);
        table.setRestaurant(restaurant);
        restaurant.getTable().add(table);
        restaurantService.updateRestaurant(restaurant);
        return "redirect:/bookings";
    }

}

还有我在RestaurantDaoImpl.java中的updateRestaurant()方法:

@Override
public void updateRestaurant(Restaurant restaurant) {
    Session session = this.sessionFactory.getCurrentSession();
    session.merge(restaurant);
    logger.info("Restaurant record updated successfully, Restaurant Details=" + restaurant);
}

任何帮助表示赞赏!

编辑:我使用的Hibernate版本是4.3.6。

另外,将我的餐厅表声明更改为:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER , mappedBy = "restaurant")
private List<RestaurantTable> table = new ArrayList<RestaurantTable>();

它给了我和以前一样的错误。

编辑:我读到的一种解决方案是将Cascade.ALL更改为不包括MERGE,因此代码如下所示:

@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.DETACH, CascadeType.REFRESH}, fetch = FetchType.EAGER , mappedBy = "restaurant")
private List<RestaurantTable> table = new ArrayList<RestaurantTable>();

它没有给我一个错误,但是它什么也没做,什么都没有改变。

您的餐厅-> RestaurantTable关系正在双方管理。 关系的只有一方可以是关系的所有者。 在这种情况下,RestaurantTable应该是关系的所有者,因为其表将具有指向另一个表的外键。

您需要更改Restaurant table属性以指示该关系由RestaurantTable restaurant属性管理。 JPA现在将使用该属性进行持久化。

将属性声明更改为

 @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER , mappedBy = "restaurant")
 private List<RestaurantTable> table = new ArrayList<RestaurantTable>();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM