Доброго времени суток, ЛОР. Проблема следующая: слой DAO используется в слое сервисов, а между ними над результатами селектов должны производиться некоторые преобразования. Для этого использую ещё один небольшой слой в виде session-бина, что как раз вызвано необходимостью проброса транзакции. Так вот, пытаюсь я пробросить транзакцию, но получаю:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
@WebService
public class AccountServiceImpl implements AccountService {
@Inject
AccountDAO accountDao;
@Inject
BOExtractor boExtractor;
...
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public Account getByEan(String ean) throws SOAPException {
try {
AccountEntity accountEntity = accountDao.getAccountByEan(ean);
return boExtractor.extractAccount(accountEntity);
} catch (AccountNotFoundException e) {
SOAPFactory sf = SOAPFactory.newInstance();
throw new SOAPFaultException(sf.createFault(e.getMessage(), new QName(FaultCode.ACCOUNT_NOT_FOUND.getFaultCode())));
}
}
...
}
@Stateless
public class AccountDAOImpl extends AbstractFiscalDAO<AccountEntity> implements AccountDAO {
@PersistenceContext(unitName = "accounts")
private EntityManager entityManager;
...
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public AccountEntity getAccountByEan(String ean) throws AccountNotFoundException {
AccountEntity accountEntity = (AccountEntity) entityManager.createNamedQuery("account.getByEAN")
.setParameter("ean", ean).getSingleResult();
...
return accountEntity;
}
}
@Stateless
public class BOExtractorImpl implements BOExtractor {
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public Account extractAccount(AccountEntity accountEntity) {
Account acc = new Account();
acc.setEan(accountEntity.getEan());
acc.setActiveAmount(accountEntity.getActiveAmount());
acc.setCardUID(accountEntity.getCard().getNumber());
acc.setCurrencyCode(accountEntity.getCurrency().getCode());
acc.setIsLocked(accountEntity.getLocked());
acc.setLimit(accountEntity.getLimit());
acc.setHolderUID(accountEntity.getHolder().getUid());
return acc;
}
...
}
Прошу обратить внимание на то, что в AccountServiceImpl#getByEan, после возвращения результата из DAO, из сущности счета (aka Account) уже невозможно получить Card и Holder. Ах да, собственно, сущность:
@Entity
@Table(name = "ACCOUNT")
@NamedQueries({
@NamedQuery(name = "account.getByEAN", query = "select a from AccountEntity a where a.ean = :ean"),
@NamedQuery(name = "account.listByHolderID", query = "select a from AccountEntity a where a.holder.uid = :uid")
})
public class AccountEntity implements Serializable {
@Id
@Column(name = "ID", nullable = false, insertable = true, updatable = true)
...
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CARD_ID")
private CardEntity card;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "HOLDER_UID")
private HolderEntity holder;
...
}
в AccountServiceImpl#getByEan, после возвращения результата из DAO, из сущности счета (aka Account) уже невозможно получить Card и Holder
Вопрос: как правильно обойти?
Заранее спасибо.