Как избежать LazyInitializationException при отправке формы в JSF? - PullRequest
0 голосов
/ 20 марта 2019

У меня много-много отношений между некоторыми сущностями.Я пытаюсь обновить объект со страницы редактирования, но когда я нажимаю кнопку отправки (я использую commandLinkbut jsf, но метод, на который ссылается атрибут действия, внутри пуст), Hibernate дает мне Lazy Initialization Exception.

org.hibernate.LazyInitializationException: failed to lazily initialize a collection, could not initialize proxy - no Session

Рабочий процесс выглядит следующим образом: я перечисляю все объекты в таблице и затем нажимаю на конкретный объект, чтобы редактировать его (он переносит меня на другую страницу).Я извлекаю весь объект с методом getAllCases() из службы, которая вызывает метод getAllCases, из DAO, которая использует метод findByAll, из HibernateGenericDAO.

Вот основная сущность:

@Entity
@Table(name = "table")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Case implements Serializable, commons.entities.Entity<Long> {

private List<Product> products;

  @ManyToMany(fetch = FetchType.LAZY)
  @Cascade(CascadeType.SAVE_UPDATE)
  @JoinTable(
      name = "join_table",
      joinColumns = {@JoinColumn(name = "CASE_ID", nullable = false, updatable = false)},
      inverseJoinColumns = {@JoinColumn(name = "PRODUCT_ID", nullable = false, updatable = false)},
      uniqueConstraints = {@UniqueConstraint(columnNames = {"CASE_ID", "PRODUCT_ID"})}
  )
  public List<Product> getProducts() {
    return products;
  }

  public void setProducts(List<Product> products) {
    this.products = products;
  }

А вот сущность Продукта.

@Entity
@Table(name = "table")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Product implements Serializable, commons.entities.Entity<Long> {

  private Long id;
  private String productName;

  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "PRODUCTS_seq")
  @SequenceGenerator(name = "CASE_PRODUCTS_seq", sequenceName = "PRODUCTS_seq", allocationSize = 1)
  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  @Column(name = "product_name", unique = true, nullable = false)
  public String getProductName() {
    return productName;
  }

  public void setProductName(String productName) {
    this.productName = productName;
  }

Это услуга

@Component
@Transactional(
    propagation = Propagation.REQUIRES_NEW,
    rollbackFor = {
        RuntimeException.class,
        Exception.class,
        UnexpectedRollbackException.class
    })
public class CasesService {

  @Autowired
  public CasesService(ICaseDAO caseDAO) {
    this.caseDAO = caseDAO;
  }

 public void saveCase(Case case) {
    caseDAO.saveCase(case);
  }

Это DAO

@Component
public class CaseDAO extends HibernateGenericDAO<Long, Case> implements ICaseDAO {

@Override
  public List<Case> getAllCases() {
    return this.findByAll();
  }

@Override
  public void saveCase(Case case) {
    this.merge(case);
  }
}

1 Ответ

0 голосов
/ 20 марта 2019

Вы можете попробовать активировать свойство конфигурации hibernate.enable_lazy_load_no_trans .

Но было бы лучше инициализировать объекты DTO со всеми данными, необходимыми для текущего взаимодействия с пользователем.

Примите серьезную подсказку к настройке:

Инициализируйте ленивые прокси или коллекции вне заданного контекста персистентности транзакции.

Хотя включение этой конфигурации может заставить LazyInitializationException уйти, этолучше использовать план извлечения, который гарантирует, что все свойства будут правильно инициализированы до закрытия сеанса.

В действительности, вам, вероятно, не следует включать этот параметр в любом случае.

В общемнастройки (когда true) улучшают механизм отложенной загрузки, так что он будет создавать новый цикл TX-> fetch-> commit при каждой отложенной инициализации, если исходный Session объект, из которого был извлечен объект, уже closed.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...