【问题标题】:lazy loading return null value延迟加载返回空值
【发布时间】:2013-07-24 16:40:28
【问题描述】:

我使用 spring 3.2、spring data 和 jpa。

我保存了一个广告对象, 保存消息后

我尝试访问来自广告的消息,但它是空的

@Entity
public class Advertisement implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@OneToMany(mappedBy="id", cascade={CascadeType.REMOVE}, fetch=FetchType.LAZY)
private Set<Message> messages;
}

@Entity
public class Message implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@ManyToOne
private Advertisement advertisement;
}

测试单元

Advertisement ads = new Advertisement();
ads = advertisementRepo.save(ads);

assertNotNull(ads);
assertNotNull(ads.getId());

Message message = new Message();
message.setAdvertisement(ads);
message = msgRepo.save(message);

ads = advertisementRepo.findOne(ads.getId());
ads.getMessages(); //return null

为什么 ads.getMessages() 不返回消息?

【问题讨论】:

    标签: spring jpa lazy-loading


    【解决方案1】:

    问题在于 JPA 无法透明地管理双向关系。在操作双向关系的一侧时,应用程序必须确保另一侧得到相应的更新。

    这可以通过编写更新关联实体的 setter 方法轻松完成。例如设置MessageAdvertisment时,可以将Message实例添加到Advertisment中的集合中:

    @Entity
    public class Message implements Serializable {
    
        ...
    
        public void setAdvertisement(Advertisement advertisement) {
            this.advertisement = advertisement;
            advertisement.getMessages().add(this);
        }
    }
    

    【讨论】:

    • 那行得通,但在广告中,我需要做: Set messages = new HashSet();在我拥有之前:设置 消息;
    • 好的,你需要初始化集合,我忘了说。
    【解决方案2】:

    在为Advertisement 分配一个新的Message 集合后,尝试保存它:

    Advertisement ads = new Advertisement();
    ads = advertisementRepo.save(ads);
    
    assertNotNull(ads);
    assertNotNull(ads.getId());
    
    Message message = new Message();
    message.setAdvertisement(ads);
    ads.setMessages(new HashSet<Message>());
    ads.getMessages().add(message);
    ads = advertisementRepo.save(ads);
    message = msgRepo.save(message);
    
    ads = advertisementRepo.findOne(ads.getId());
    ads.getMessages(); //return null
    

    【讨论】:

      【解决方案3】:

      这将返回 null,因为您先保存非拥有实体,然后再保存拥有实体。如果您在ads 之前保存message,它应该返回非空值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-09
        • 1970-01-01
        • 2019-03-12
        • 2018-04-12
        相关资源
        最近更新 更多