我有一个问题要问。我在尝试将新属性保存到数据库时收到此错误。专栏' property_id'不能为空。当tryint将功能列表保存到数据库中时发生异常。由于某种原因,插入的属性和功能之间没有关系。对象PropertyFeature中不存在Property_id。
以下是我的数据:
table 'property':
id
name
table 'features'
id
title
property_id [not null]
实体属性
@Table(name = "property")
public class Property extends...{
@Column(name = "name", nullable = true)
private String name;
@OneToMany(mappedBy = "property", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set<PropertyFeature> features;
public Property() {
}
public Property(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<PropertyFeature> getFeatures() {
return features;
}
public void setFeatures(Set<PropertyFeature> features) {
this.features = features;
}
}
实体PropertyFeature
@Entity
@Table(name = "property_feature")
public class PropertyFeature extends ... {
@Column(name = "title", nullable = false)
private String title;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
private Property property;
public PropertyFeature() {
}
public PropertyFeature(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Property getProperty() {
return property;
}
public void setProperty(Property property) {
this.property = property;
}
}
SPRING CONTROLLER
@Controller
@RequestMapping(value="/account")
public class AccountController {
@Autowired
PropertyServiceImpl propertyServiceImpl;
@RequestMapping(method = RequestMethod.GET, value = "/test")
public String accountPage(HttpServletRequest request, HttpServletResponse response, ModelMap model) {
Property property = propertyServiceImpl.load(12L);
ArrayList<PropertyFeature> test = new ArrayList<PropertyFeature>();
test.add(new PropertyFeature("Feature 1"));
test.add(new PropertyFeature("Feature 2"));
test.add(new PropertyFeature("Feature 3"));
model.put("property", property);
model.put("testList", test);
return "/test";
}
@RequestMapping(method = RequestMethod.POST, value = "/test")
public String accountPost(HttpServletRequest request, HttpServletResponse response, Property property) {
propertyServiceImpl.update(property);
return "/test";
}
}
JSP FORM:
<form:form method="post" commandName="property">
Name <form:input path="name" type="text" name="name" value="" />
Features
<form:select multiple="true" path="features">
<form:options items="${testList}" itemValue="title" itemLabel="title"/>
</form:select>
<input type="submit" name="submit" value="Test" />
答案 0 :(得分:1)
Hibernate需要property_feature上的外键才能加入ManyToOne
映射属性。您没有通过使用@JoinColumn
提供列,因此Hibernate使用其默认机制在您的模式中创建了一个列。这在2.2.5.3.1.4节中描述here。
您已将Property映射为非可选属性,因此Hibernate希望您在保存前始终在Property
上设置PropertyFeature
。您已将PropertyFeature
添加到Property的列表中,但尚未在Property
上设置PropertyFeature
。
我建议在属性类中添加一个方法,如下所示:
public void addFeature(PropertyFeature feature) {
feature.setProperty(this);
features.add(feature);
}
然后在你的控制器中你可以写:
Property property = propertyServiceImpl.load(12L);
property.addFeature(new PropertyFeature("Feature 1"));
答案 1 :(得分:0)
我看到的问题是。为了使它成为我想要的方式,我需要第三个表来连接属性和功能。在这种情况下,我可以指定
@JoinTable(name="property_features", joinColumns={@JoinColumn(name="property_id")}, inverseJoinColumns={@JoinColumn(name="id")})
在这种情况下,hibernate会创建第3个表,我不必将对象属性设置为evey PropertyFeature实例。这很好但我不喜欢这种情况下的第三个表。
我想我会将我的Property实体方法setFeatures更新为类似的东西
public void setFeatures(Set<PropertyFeature> features) {
for(PropertyFeature pf : features)
pf.setProperty(this);
this.features = features;
}
经测试,按预期工作。让我知道伙伴们是否有更好的方法来处理它只有2个表。感谢