【问题标题】:Spring JPA Hibernate object null when saving ManyToOne保存ManyToOne时Spring JPA Hibernate对象为null
【发布时间】:2016-08-19 13:19:27
【问题描述】:

我有两个双向关系的实体(ManyToOne、OneToMany) 两张桌子的房子和房间。房子有很多房间。
我需要用它的地址和两个(以后可能更多)房间来保存房子。 下面的代码添加了没有房间的房子和地址( room = null )。

我怎样才能做到这一点?

我关于房间的输入是否正确?例如在 PHP 中,我将拥有 name="roomName[]"

我认为 Hibernate 会为我做所有事情 :) 尤其是当我使用 cascadeType.ALL 时

@Entity
@Data
public class House {

  @Id
  @GeneratedValue(strategy = IDENTITY)
  private Long id;

  private String name;

  @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
  @JoinColumn(name = "address_id")
  private PostalAddress address;

  @OneToMany(cascade = CascadeType.ALL, mappedBy = "house", fetch = FetchType.EAGER)
  private Set<Room> rooms;
}

房间

@Entity
@Data
public class Room {

  @Id
  @GeneratedValue(strategy = IDENTITY)
  private int id;

  private String name;

  @NotNull
  private int capacity;

  @NotNull
  @ManyToOne
  @JoinColumn(name = "house_id")
  private House house;
}

创建数据库入口表单

<input type="text" name="name" placeholder="house name..." />
<input type="text" name="address.addressLocality" placeholder="locality" />
<input type="text" name="address.postalCode" placeholder="postalCode" />
<input type="text" name="address.streetAddress" placeholder="street" />
<input type="text" name="room.name" placeholder="room name" />
<input type="text" name="room.capacity" placeholder="capacity" />
<input type="text" name="room.name" placeholder="room name" />
<input type="text" name="room.capacity" placeholder="capacity" />

终于是我的控制器和存储库

public interface RoomRepository extends CrudRepository<Room, Long> {
}

@RequestMapping(value = "/create", method = RequestMethod.POST)
public String saveHouse(@ModelAttribute("house/new") House house, BindingResult bindingResult, Model model) {

  houseRepository.save(house);

  return "redirect:/house/list";

}

// 重要编辑

我有提示可能是什么问题,但我无法解决这个问题。我正在使用百里香叶。当 House 有很多房间(设置房间)时,包含房间输入的表单部分不正确。默认情况下,我在表格中显示 4 行(房间名称、容量)

<tr th:each="i,iterStat : ${#numbers.sequence( 1, 4)}">
   <td class="col-xs-9 col-md-9"><input type="text" name="rooms.name" th:value="ROOM + ' ' + ${iterStat.current}"  class="form-control"/> </td>
   <td class="col-xs-2 col-md-2"><input type="number" name="rooms.capacity" min="1" step="1" value="4" class="form-control"/> </td>
   <td class="col-xs-1 col-md-1"><button type="button" class="btn red pull-right" onclick="removeTableRow(this)"> <i class="fa fa-trash"></i> </button></td>
</tr>

当用户想要添加更多或更少的房间时,他(使用 jQuery)删除/添加带有输入的表格行 我试图将输入名称更改为

th:field="*{rooms[${iterStat.current}].name}"

但这不是它。那么如何填充这些字段呢?

【问题讨论】:

  • 您是否在 RoomRepository saveHouse 方法中的房屋对象中获得空间?
  • 你调试过应用程序,房子里有没有你保存在存储库中的房间? :)

标签: java spring hibernate jpa crud


【解决方案1】:

尝试使用 House 实体映射:

@OneToOne(fetch = FetchType.EAGER, mappedBy = "house", cascade = {CascadeType.ALL})
private PostalAddress address;

@OneToMany(fetch = FetchType.EAGER, mappedBy = "house", cascade = {CascadeType.ALL}, orphanRemoval = true)
private Set<Room> rooms;

邮政地址:

@OneToOne
@JoinColumn(name="house")
private House house;

房间:

@NotNull
@ManyToOne
@JoinColumn(name="house")
private House house;

【讨论】:

  • 在应用您的建议后,应用程序不会保存任何提供嵌套异常的内容。我猜您尝试更改 PostalAddress 实体是因为其他(房间、房屋)更改以避免 Hibernate.AnnotationException: Unknown mappedBy on PostalAddress。基本上我宁愿不改变已经有效的东西——房子的地址。
  • 好吧,也许我误解了你的问题。当您使用版本代码保存时 - House 是否包含任何房间?
  • 我在 houseRepository.save(house) 中标记了 braekpoint 并且 Room 为空
  • 我也将表单字段名称从 room.name 更改为 rooms.name(这是我在 House Entity 中的对象。仍然为空
  • 所以这是你的表单的问题,而不是 Hibernate 级联。
猜你喜欢
  • 2018-09-04
  • 2016-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-09
  • 2018-08-05
相关资源
最近更新 更多