AOP记录器方面的LazyInitializationException

时间:2014-04-14 12:43:42

标签: spring jsf jpa

我有一个使用Spring,JSF JPA和Hibernate构建的应用程序 我有一个方面,"手表"每次更新*,从我的应用程序服务层创建*,删除*方法。此方面记录方法params,将toString应用于每个参数,并将它们记录在数据库中。问题是我在jsf中使用域对象,当我尝试更新*时,当toString()应用于方法参数时,我得到一个LazyInitializationException。
一种解决方案是从toString中删除代表其他对象的所有参数,但操作没有意义,因为我没有记录我感兴趣的细节。
即。我有一个名为Price的实体,它具有依赖性PriceList:

public class Price extends BaseEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    @Column(name = "price")
    private Double price;

    //bi-directional many-to-one association to TelCoPriceList
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "price_list_id")
    private PriceList priceList;
.....................
}

价格用于AddPriceForm.xhtml,这是jsf表单。 JSF AddPriceMB引用了PriceService来执行实际更新 价格服务受到监控"通过这方面:

@Aspect
@Named("auditLogAspectImpl")
public class AuditLogAspectImpl implements AuditLogAspect {

@Inject
private UserService userService; 

@Inject
private AuditLogService auditLogService;

@Override
@AfterReturning(pointcut = "execution(* com.videanuadrian.core.impl.services..*.save*(..)) or execution(* com.videanuadrian.core.impl.services..*.update*(..)) or execution(* com.videanuadrian.core.impl.services..*.delete*(..))", returning = "retVal")
public boolean afterLogEvent(JoinPoint joinPoint,Object retVal) {

    String className = joinPoint.getTarget().getClass().getName();
    String methondName = joinPoint.getSignature().getName();

...................................................................      
    StringBuffer logMessage = new StringBuffer();       
    Object[] args = joinPoint.getArgs();    

    //for login action we only get the username and hash the password
    if (methondName.compareTo("login") == 0){           
        logMessage.append(args[0]);         
    }else {

        int argsLen = args.length;
        //else log all the parameters
        for (int i = 0; i < argsLen; i++) {
            // this is where the exception occurs !!!!!!!!!!!!!!!!!!!!!!!!!!!
            logMessage.append(args[i]).append(",");
        }

        if (argsLen > 0) {
            logMessage.deleteCharAt(logMessage.length() - 1);
        }
    }

    //some save/update methods return Boolean
        Boolean status = false;
        if (retVal instanceof Boolean){
            status = (Boolean) retVal;
        }

        //some return the ID of the object inserted,and if these methods return an integer the status is true, if they return null, the status si false
        if (retVal instanceof Integer){
            if (retVal!=null)
                status = true;  
        }

    auditLogService.addAuditLogEvent(uid, className+"."+methondName, status,logMessage.toString());     
    return true;
}

在先前版本上,我没有遇到此问题,因为我使用过DTO对象,并且在服务层中执行了DTO和域对象之间的转换。错误非常明显,因为我的会话很久以前就关闭了,而不是我执行toString()操作的时间。 任何想法如何在不使用openSessionInView或扩展持久化上下文的情况下实现这一目标?或许我的方法不好......

0 个答案:

没有答案