【问题标题】:Hibernate Annotations with a collection带有集合的休眠注释
【发布时间】:2011-03-23 01:27:56
【问题描述】:

我正在尝试使用休眠注释来实现我的模型。我有 3 个类,图像,人物和标签。 Tags 是一个由 4 个字段组成的表,一个 id、personId、imageId 和一个 createdDate。人物有姓名、身份证、生日等字段。我的图像类定义如下:

@Entity
@Table(name="Image")
public class Image {
    private Integer imageId;
    private  Set<Person> persons = new HashSet<Person>();

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    public Integer getImageId() {
        return imageId;
    }

    public void setImageId(Integer imageId) {
        this.imageId = imageId;
    }

    @ManyToMany
    @JoinTable(name="Tags",
                joinColumns = {@JoinColumn(name="imageId", nullable=false)},
                inverseJoinColumns = {@JoinColumn(name="personId", nullable=false)})
    public Set<Person> getPersons() {
        return persons;
    }

    public void setPersons(Set<Person> persons) {
        this.persons = persons;
    }

如果我删除 getPersons() 方法上的注释,我可以使用这些类并添加和删除记录。我想获取带有图像的所有标签,并且我正在尝试使用一组标签。我不断收到以下错误:

org.hibernate.LazyInitializationException - failed to lazily initialize a collection of role: com.exmaple.persons, no session or session was closed

有人可以帮助我,让我知道我做错了什么吗?

谢谢

【问题讨论】:

    标签: java hibernate configuration collections annotations


    【解决方案1】:

    此错误消息 - 实际上与您的关联映射策略或注释无关 - 意味着您试图在 Session 关闭后访问您的域对象之一上的延迟加载集合。

    解决方案是禁用此集合的延迟加载,在关闭Session 之前显式加载集合(例如,通过调用foo.getBars().size()),或者确保Session 保持打开状态直到它不再需要。

    如果你不确定什么是延迟加载,here is the section in the Hibernate manual

    【讨论】:

    • 我会接受这个答案。我很感激帮助。我仍在阅读 spring 文档中的第 10 章和第 13 章。有机会我会发布更新。
    【解决方案2】:

    感谢马特的回复。我现在很困惑。我检索图像的查询如下所示:

    public Image findByImageId(Integer imageId) {
        @SuppressWarnings("unchecked")
        List<Image> images = hibernateTemplate.find(
                "from Image where imageId=?", imageId);
        return (Image)images.get(0);
    }
    

    我认为我可以调用单个 hql 查询,如果我的映射正确,它将带回相关数据。

    我在这个链接hibernate mappings

    2.2.5.3.1.3. Unidirectional with join table
    A unidirectional one to many with join table is much preferred. This association is described through an @JoinTable.
    
    @Entity
    public class Trainer {
        @OneToMany
        @JoinTable(
                name="TrainedMonkeys",
                joinColumns = @JoinColumn( name="trainer_id"),
                inverseJoinColumns = @JoinColumn( name="monkey_id")
        )
        public Set<Monkey> getTrainedMonkeys() {
        ...
    }
    
    @Entity
    public class Monkey {
        ... //no bidir
    }         Trainer describes a unidirectional relationship with Monkey using the join table TrainedMonkeys, with a foreign key trainer_id to Trainer (joinColumns) and a foreign key monkey_id to Monkey (inversejoinColumns).
    

    【讨论】:

    • 有人对我的后续问题有任何额外的 cmets 吗?谢谢
    • 我不确定我是否理解您在这里的要求,但是您返回第一个 Image 实例的查询实际上会返回该对象 - 但 Hibernate 延迟加载 Image.trainers 集合,错误消息所指的。这是您在关闭会话之前必须加载的集合,或者标记为非延迟加载。
    • 我认为这就是我感到困惑的地方。因此,我的查询获取了具有延迟加载的 set 的图像对象。所以当我要求一个特定的图像对象时,它基本上是一个空集?我相信,因为我使用的是 hibernateTemplate,所以会话是为我处理的。因此,当我执行 hibernate.find("from Image ...) 时,我必须再次查找 person 对象并填充该集合?
    • 如果您使用的是 Spring,请查看手册中与 transaction management with Hibernate (13.3.3, 13.3.4, and 13.3.5) 相关的部分。如果不存在,HibernateTemplate 将打开一个 Session,或者如果您的方法调用在事务中,则使用现有的 Session。您收到错误是因为您在 Session 关闭后访问 Set ,这可能是在方法调用后自动完成的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    • 2011-07-22
    • 2023-03-18
    • 2012-05-06
    • 1970-01-01
    相关资源
    最近更新 更多