简体   繁体   中英

Spring Data 2.0.x AuditorAware getCurrentUser method throws AbstractMethodError

I am trying to implement AuditorAware into my web application. Below is the list of my library version:

  • jsf 2.2.13
  • hibername 5.1.3.Final
  • spring 5.0.3.RELEASE
  • spring-data 2.0.3.RELEASE
  • spring-security 5.0.1.RELEASE

This is my persistence config file:

@Configuration
@EnableJpaAuditing(auditorAwareRef = "auditorAware")
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableTransactionManagement
public class PersistenceContext
{
     @Bean
     public AuditorAware<AccountModel> auditorAware()
     {
         return new AuditorAwareImpl();
     }
}

And this is my AuditorAwareImpl class:

public class AuditorAwareImpl implements AuditorAware<AccountModel>
{
    @Override
    public Optional<AccountModel> getCurrentAuditor()
    {
        return Optional.ofNullable((AccountModel) SecurityContextHolder.getContext().getAuthentication().getPrincipal());
    }
}

AccountModel:

@Entity(name = "Account")
@Table(name = "account")
public class AccountModel extends BaseModel implements UserDetails
{
    private static final long serialVersionUID = -4792614546550769652L;

    @Column(name = "username", length = 20, nullable = false)
    private String username;

    @Column(name = "password", length = 100, nullable = false)
    private String password;

    @Column(name = "email", length = 100, nullable = false)
    private String email;

    @Column(name = "accPackage", length = 2, nullable = false)
    private String accPackage;

    @OneToMany(mappedBy = "account", cascade = CascadeType.ALL)
    private Set<RoleModel> role = new HashSet<RoleModel>();

    @Transient
    private transient Set<GrantedAuthority> authorities;
}

BaseModel:

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseModel implements Serializable
{
    private static final long serialVersionUID = -8027746305948051121L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false, updatable = false)
    private Integer id;

    @CreatedBy
    @ManyToOne
    @JoinColumn(name = "createdBy", nullable = true, updatable = false)
    private AccountModel createdBy;

    @CreatedDate
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "dateCreated", nullable = false, updatable = false)
    private Date dateCreated;

    @LastModifiedBy
    @ManyToOne
    @JoinColumn(name = "modifiedBy", insertable = false)
    private AccountModel modifiedBy;

    @LastModifiedDate
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "dateModified", insertable = false)
    private Date dateModified;

    @Version
    @Column(name = "verCtrl", nullable = false)
    private Integer version;
}

When I try to persist an object, AbstractMethodError will be thrown:

Caused by: java.lang.AbstractMethodError: com.project.core.AuditorAwareImpl.getCurrentAuditor()Ljava/lang/Object;
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy71.getCurrentAuditor(Unknown Source)
    at org.springframework.data.auditing.AuditingHandler.touchAuditor(AuditingHandler.java:166)
    at org.springframework.data.auditing.AuditingHandler.touch(AuditingHandler.java:145)
    at org.springframework.data.auditing.AuditingHandler.markCreated(AuditingHandler.java:125)
    at org.springframework.data.jpa.domain.support.AuditingEntityListener.touchForCreate(AuditingEntityListener.java:83)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.hibernate.jpa.event.internal.jpa.ListenerCallback.performCallback(ListenerCallback.java:35)
    ... 124 more


UPDATE

After I have changed my Spring Data from 2.x to 1.x, it works, no more exception. I think the problem is with the return data type of the getCurrentUser() method. In 1.x, return datatype is simply your custom UserDetails object, but in 2.x, the return datatype is Optional<CustomModel> . Could it possible be the cause of error?

Yes, cause of this error is change in the return data type of the getCurrentUser() method. In 2.x versions, this is changed to Optional (In 1.x versions, the return type was simply T). There are two ways to solve this :

  1. Downgrade Spring Data from 2.x to 1.x
  2. But, as I had to keep Spring Data on 2.x version, I simply changed the code from

    @Override public String getCurrentAuditor() { return currentUser(); }

    to

    @Override public Optional<String> getCurrentAuditor() { return Optional.of(currentUser()); }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM