2015-11-05 73 views
1

我有一个要求,我必须存储为每个插入/更新审计信息/删除。要存储的信息将是更新时间用户标识如何将参数传递给回调方法

我从this tutorial,我可以使用实体监听和回调方法,如@PrePersist教训。

我知道如何处理这个回调方法里面更新时间但我不知道我怎么可以设置用户id在实体回调方法里面:

@PrePersist 
private void prePersist() { 
    this.updateTime = new Date(); 
    this.userId = ???; 
} 

如何传递当前用户的回调方法的ID?

+0

你任何机会使用弹簧(安全)? – Forkmohit

+0

@Forkmohit不,我没有使用它。 – user3359005

回答

0

你不能传递任何信息,直接与Hibernate或者JPA API的回调方法。

但还有另一种常用的解决方案:ThreadLocal

一个ThreadLocal存储当前正在运行的线程的静态变量。由于请求通常只在一个线程中执行,因此可以从回调方法/侦听器访问该信息。一些UI框架为您创建了一个ThreadLocal

例如JSF提供了一个与FacesContext.getCurrentInstance()。所以在JSF,你可以拨打:

FacesContext.getCurrentInstance().getExternalContext().getRemoteUser() 

或者在RequestContextHolder

((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getRemoteUser() 

如果你有没有这样的框架,你可以建立自己的ThreadLocal

public final class UserIdHelper { 
    // You can add the static ThreadLocal to any class, just as an example 
    private static final ThreadLocal<String> userIds = new ThreadLocal<>(); 

    public static void setCurrentUserId(String userId) { 
    userIds.set(userId); 
    } 

    public static void getCurrentUserId() { 
    return userIds.get(); 
    } 

    public static void removeCurrentUserId() { 
    return userIds.remove(); 
    } 
} 

现在,您可以设置用户idFilter或只是围绕y我们呼吁JPA:

UserIdHelper.setCurrentUserId(request.getRemoteUser()); 
try { 
    // ... Execute your JPA calls ... 
} finally { 
    UserIdHelper.removeCurrentUserId(); 
} 

重要的是要去除用户idfinally块 - 否则在同一个线程中运行的后续请求可能“劫持”你以前用户id

要访问您的回调方法的信息:

@PrePersist 
private void prePersist() { 
    this.createdBy = UserIdHelper.getCurrentUserId(); 
}