【问题标题】:JsonMappingException with Arrays of object in spring-jpaJsonMappingException 与 spring-jpa 中的对象数组
【发布时间】:2014-10-21 16:15:13
【问题描述】:

当我尝试从我的 dbms 获取项目时出现错误。跟随错误

com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.pharmawizardcabinet.core.entity.cabinet.Cabinet.listaFarmaci, could not initialize proxy - no Session (through reference chain: com.pharmawizardcabinet.web.beans.ResponseCabinet["cabinet"]->com.pharmawizardcabinet.core.entity.cabinet.Cabinet["listaFarmaci"])

这是我的容器

@Entity
@Table(name = "Cabinet")
public class Cabinet implements Serializable {

    private static final long serialVersionUID = 7311927404447970875L;
    @Id
    @Column(name = "Id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long Id;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "cabinet")
    private List<Farmaco> listaFarmaci;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "user")
    private User user;

    @Column(name = "timestamp")
    @Temporal(TemporalType.DATE)
    private Date setLastModified;

    public Cabinet() {
    }

    @PostPersist
    @PostUpdate
    private void setLastUpdate() {
        this.setLastModified = new Date();
    }

    public List<Farmaco> getListaFarmaci() {
        return listaFarmaci;
    }

    public void setListaFarmaci(List<Farmaco> listaFarmaci) {
        this.listaFarmaci = listaFarmaci;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Long getId() {
        return Id;
    }

    public void setId(Long id) {
        Id = id;
    }

    public Date getSetLastModified() {
        return setLastModified;
    }

    public void setSetLastModified(Date setLastModified) {
        this.setLastModified = setLastModified;
    }

}

这就是物品

@Entity
@Table(name = "Farmaco")
public class Farmaco implements Serializable {

    private static final long serialVersionUID = -152536676742398255L;

    public Farmaco() {
        // TODO Auto-generated constructor stub
    }

    @Column(name = "nome_farmaco")
    private String nome;

    @Column(name = "codice")
    private String codice;

    @Column(name = "azienda")
    private String azienda;

    @Id
    @Column(name = "Id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long Id;

    @Column(name = "scadenza")
    @Temporal(TemporalType.DATE)
    private Date scadenza;

    @Enumerated(EnumType.STRING)
    @Column(name = "posologia")
    private Posologia posologia;

    @Column(name = "quantita")
    private Integer quantita;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "note")
    private Note note;

    @ManyToOne(cascade =CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "cabinet_id")
    private Cabinet cabinet;

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getCodice() {
        return codice;
    }

    public void setCodice(String codice) {
        this.codice = codice;
    }

    public String getAzienda() {
        return azienda;
    }

    public void setAzienda(String azienda) {
        this.azienda = azienda;
    }

    public Long getId() {
        return Id;
    }

    public void setId(Long id) {
        Id = id;
    }

    public Date getScadenza() {
        return scadenza;
    }

    public void setScadenza(Date scadenza) {
        this.scadenza = scadenza;
    }

    public Posologia getPosologia() {
        return posologia;
    }

    public void setPosologia(Posologia posologia) {
        this.posologia = posologia;
    }

    public Integer getQuantita() {
        return quantita;
    }

    public void setQuantita(Integer quantita) {
        this.quantita = quantita;
    }

    public Note getNote() {
        return note;
    }

    public void setNote(Note note) {
        this.note = note;
    }

    public Cabinet getCabinet() {
        return cabinet;
    }

    public void setCabinet(Cabinet cabinet) {
        this.cabinet = cabinet;
    }

}

控制器是这个

@Component("managerCabinet")
public class ManagerCabinet {

    private static Logger logger = Logger.getLogger(ManagerCabinet.class);

    @PersistenceContext(name = "pwcabinet-jpa")
    private EntityManager entityManager;

    @Transactional
    public Cabinet getCabinetByUser(User user) {
        logger.debug("[getCabinetByUser] user: " + user.getId());
        return _getCabinetByUser(user);
    }
    private Cabinet _getCabinetByUser(User user) {
        logger.debug("[_getCabinetByUser] user: " + user.getId());
        User find = entityManager.find(User.class, user.getId());
        Query searchCabinetByUser = entityManager.createQuery("Select c from Cabinet c where c.user = :userId", Cabinet.class);
        searchCabinetByUser.setParameter("userId", find);
        Cabinet cabinetSearch = (Cabinet) searchCabinetByUser.getSingleResult();
        cabinetSearch.setUser(find);
        return cabinetSearch;
    }

}

但我继续收到错误。

如果我以这种方式使用注解@JsonIgnore

@JsonIgnore
public List<Farmaco> getListaFarmaci() {
    return listaFarmaci;
}

它们有效,但我的结果中需要这些信息。怎么解决?

【问题讨论】:

    标签: java spring jpa jackson


    【解决方案1】:

    当您的方法private Cabinet _getCabinetByUser(User user) 返回时,Cabinet 实例处于“分离”状态,即。不再与持久性上下文相关联。

    当一个项目处于分离状态时,非急切获取的关联可以再被访问。

    因为@OneToMany 的默认获取是 Lazy,那么在你的情况下

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "cabinet")
    private List<Farmaco> listaFarmaci;
    

    一旦加载的 Cabinet 与持久化上下文分离,就无法再访问字段 listaFarmaci。

    您有多种处理方法,包括:

    1. 将字段标记为急切获取(不好,因为无论是否需要,总是急切获取)。
    2. 强制持久性上下文保持打开状态,直到所有处理完成通常称为 OpenSessionInView 模式(或反模式),具体取决于您的观点:http://java.dzone.com/articles/open-session-view-design
    3. 确保在分离之前初始化用例所需的所有数据。有多种方法可以实现这一目标:

    简单地访问集合是某种方式,例如通过调用 size() 但这可能不适用于所有 JPA 提供程序。

    在加载机柜的 JPQL 查询中指定 FETCH JOIN(尽管这有副作用)。 http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Join_Fetching

    【讨论】:

    • 我已经修改了_getCabinetByUser(User user) 来检查listaFarmaco 的大小并且它可以工作。谢谢
    猜你喜欢
    • 2019-07-11
    • 2021-03-13
    • 2013-05-11
    • 1970-01-01
    • 2021-06-13
    • 2020-07-25
    • 2015-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多