@IndexColumn的使用导致seq_num为0

时间:2010-10-29 17:58:30

标签: java hibernate jpa

我想使用@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;

1 个答案:

答案 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或   a Map)需要特殊   考虑。 如果是属性的话   关联类显式映射   索引值,使用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元素并将多个设置为   一个@JoinColumninsertable和   updatablefalse此解决方案是   没有优化,会产生一些   额外的UPDATE语句。

总而言之,如果将索引列映射为目标实体的属性不是问题,那么这将是我的建议(即第一个映射)。

参考