我想使用@IndexColumn来设置用户输入的某些数据的序号。我使用的是Spring 2.5.6,JBoss 5.1(JPA 1.0)。
对于我的父类
@Entity
@Table(name="material")
public class Material implements Serializable {
.
.
/**
* List of material attributes associated with the given material
*/
@OneToMany(mappedBy = "material", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@IndexColumn(name="seq_number", base=0, nullable = false)
private List<MaterialAttribute> materialAttributes;
public void addMaterialAttribute(List<MaterialAttribute> attribs)
{
if(CollectionUtils.isNotEmpty(attribs))
{
for(MaterialAttribute attrib : attribs)
{
attrib.setMaterial(this);
}
this.setMaterialAttributes(attribs);
}
}
}
为我的孩子上课
@Entity
@Table(name="material_attribute")
public class MaterialAttribute implements Serializable
{
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "material_id", referencedColumnName = "id", updatable=false, nullable = true, unique = false)
private Material material;
@Column(name = "seq_number", insertable=false, updatable=false, nullable = false)
private int seqNumber;
}
对于服务类
public void save(MaterialCommand pCmd)
{
Material material = new Material(pCmd.getName());
//convert from command object to entity object
List<MaterialAttribute> attribs = new ArrayList<MaterialAttribute>();
if(CollectionUtils.isNotEmpty(pCmd.getAttribs()))
{
Iterator<MaterialAttributeCommand> iter = pCmd.getAttribs().iterator();
while(iter.hasNext())
{
MaterialAttributeCommand attribCmd = (MaterialAttributeCommand) iter.next();
MaterialAttribute attrib = new MaterialAttribute();
attrib.setDisplayName(attribCmd.getDisplayName());
attrib.setValidationType(attribCmd.getValidationType());
attribs.add(attrib);
}
}
material.addMaterialAttribute(attribs);
this.getMaterialDAO().saveMaterial(material);
}
我正在获取数据库中的条目,但对于集合中的每个项目,seq_number始终为零。
我必须假设这是我保存数据的方式,但我只是没有看到它。
我已经能够解决以下问题(删除了mappedBy):
@Entity
@Table(name="material")
public class Material implements Serializable {
/**
*
*/
private static final long serialVersionUID = 5083931681636496023L;
@Column(name="name", length=50, nullable=false)
private String mName;
/**
* List of material attributes associated with the given material
*/
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@IndexColumn(name="seq_number", base=0)
@JoinColumn(name="material_id",nullable=false)
private List<MaterialAttribute> materialAttributes;
@Entity
@Table(name="material_attribute")
public class MaterialAttribute implements Serializable
{
/**
*
*/
private static final long serialVersionUID = -196083650806575093L;
/**
* identifies the material that these attributes are associated with
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "material_id", insertable=false, updatable=false, nullable = true, unique = false)
private Material material;
@Column(name = "seq_number", insertable=false, updatable=false)
private int seqNumber;
答案 0 :(得分:4)
使用Hibernate映射 双向 索引列表有点棘手,但在文档的2.4.6.2.1. Bidirectional association with indexed collections部分中有所介绍(大胆是我的):
2.4.6.2.1. Bidirectional association with indexed collections
双向关联,其中一个 end是一个索引集合(即。 表示为
@OrderColumn
或 aMap
)需要特殊 考虑。 如果是属性的话 关联类显式映射 索引值,使用mappedBy
允许:@Entity public class Parent { @OneToMany(mappedBy="parent") @OrderColumn(name="order") private List<Child> children; ... } @Entity public class Child { ... //the index column is mapped as a property in the associated entity @Column(name="order") private int order; @ManyToOne @JoinColumn(name="parent_id", nullable=false) private Parent parent; ... }
但是,如果没有这样的财产 孩子班,我们想不到 这种联想是真实的 双向(有信息 可以在一端获得 没有的协会 另一端:索引)。在这 case,我们不能将集合映射为
mappedBy
。相反,我们可以使用 以下映射:@Entity public class Parent { @OneToMany @OrderColumn(name="order") @JoinColumn(name="parent_id", nullable=false) private List<Child> children; ... } @Entity public class Child { ... @ManyToOne @JoinColumn(name="parent_id", insertable=false, updatable=false, nullable=false) private Parent parent; ... }
请注意,在此映射中, 收藏价值的结束 协会负责 更新外键。
实际上,第二个映射正是如何将一对多方作为拥有方映射双向一对多。虽然这是可能的,但您需要注意这种映射将在优化的SQL下生成,如2.2.5.3.1.1. Bidirectional [一对多]关系部分所述:
要将双向映射到多个, 以一对多的方式作为 拥有方,你必须删除
mappedBy
元素并将多个设置为 一个@JoinColumn
为insertable
和updatable
到false
。 此解决方案是 没有优化,会产生一些 额外的UPDATE语句。
总而言之,如果将索引列映射为目标实体的属性不是问题,那么这将是我的建议(即第一个映射)。