like Gavin soad: ThreadLocal is the solution.
Heres my solution, but you need base classes for all your session- and entitybeans:
Code:
public class PropagateSessionContextInterceptor {
  
  @AroundInvoke
  public Object myInterceptor(InvocationContext ctx) throws Exception
  {
      BaseSessionBean sb = (BaseSessionBean)ctx.getBean();
      BaseEntity.setSessionContext(sb.ctx);
      Object o = ctx.proceed();
      return o;
  }
  
}
Code:
@Interceptors( {PropagateSessionContextInterceptor.class})
public class BaseSessionBean {
  @PersistenceContext(unitName = "foobar")
  protected EntityManager manager;
  @Resource
  public SessionContext ctx;
}
Code:
@MappedSuperclass
public abstract class BaseEntity {
  static final ThreadLocal<SessionContext> sessionContext = new ThreadLocal<SessionContext>();
  static SessionContext getSessionContext() {
    return sessionContext.get();
  }
  static void setSessionContext(SessionContext ctx) {
    sessionContext.set(ctx);
  }
  
  protected long id;
  protected int version;
  protected String createdBy;
  protected String updatedBy;
  protected Date createdTime;
  protected Date updatedTime;
  public void setVersion(int version) {
    this.version = version;
  }
  @Basic
  public String getCreatedBy() {
    return createdBy;
  }
  public void setCreatedBy(String createdBy) {
    this.createdBy = createdBy;
  }
  @Basic
  public String getUpdatedBy() {
    return updatedBy;
  }
  public void setUpdatedBy(String updatedBy) {
    this.updatedBy = updatedBy;
  }
  @Basic
  public Date getCreatedTime() {
    return createdTime;
  }
  public void setCreatedTime(Date createdTime) {
    this.createdTime = createdTime;
  }
  @Basic
  public Date getUpdatedTime() {
    return updatedTime;
  }
  public void setUpdatedTime(Date updatedTime) {
    this.updatedTime = updatedTime;
  }
  @PrePersist
  public void handleCreate() {
    try {
      setCreatedTime(new Date());
      Principal callerPrincipal = getSessionContext().getCallerPrincipal();
      setCreatedBy(callerPrincipal == null ? null : callerPrincipal.getName());
    }
    catch (RuntimeException e) {
      e.printStackTrace();
    }
  }
  @PreUpdate
  public void handleUpdate()  {
    try {
      setUpdatedTime(new Date());
      Principal callerPrincipal = getSessionContext().getCallerPrincipal();
      setUpdatedBy(callerPrincipal == null ? null : callerPrincipal.getName());
    }
    catch (RuntimeException e) {
      e.printStackTrace();
    }
  }
  
}