Spring AOP for database operation

≯℡__Kan透↙ 提交于 2020-01-06 08:52:05

问题


I am working in a spring,hibernate project and database is oracle. I have DAO layer for persistence related operations.

In all my tables, I have create_date and update_date columns representing the timestamp when a row is inserted and updated in the tables respectively.

There is a requirement that I have to update the above two mentioned timestamp columns of that particular table for which the request is meant to whenever any insert/update operation happens.For example, If my DAO layer has two methods, say m1 and m2 responsible for impacting t1 and t2 tables respectively. Now, if m1 method is invoked, then timestamp columns of t1 table will be updatedi.e. For insert, create_date column will be updated and for any update update_date column will be updated.

I have idea of Spring AOP so I was thinking to use AOP to implement the above requirement, though, i am not quite sure if it can be achieved using AOP.

Please let me know if I can use AOP to fulfill this requirement. And if it is possible, then please provide me the inputs how to implement it.


回答1:


I have implemented update date feature for one of the modules in my application using Spring AOP. PFB code for your reference

Hope this will help. I wonder if one can have pointcuts for variable as well.I know its might not possible with spring's aspect j implementation.But any work around guys :P

    **
    * @author Vikas.Chowdhury
    * @version $Revision$ Last changed by $Author$ on $Date$ as $Revision$
    */
   @Aspect
   @Component
public class UpdateDateAspect
{
    @Autowired
    private ISurveyService surveyService;

    Integer surveyId = null;

    Logger gtLogger = Logger.getLogger(this.getClass().getName());

    @Pointcut("execution(* com.xyz.service.impl.*.saveSurvey*(..)))")
    public void updateDate()
    {

    }

    @Around("updateDate()")
    public Object myAspect(final ProceedingJoinPoint pjp)
    {

        // retrieve the runtime method arguments (dynamic)
        Object returnVal = null;
        for (final Object argument : pjp.getArgs())
        {

            if (argument instanceof SurveyHelper)
            {
                SurveyHelper surveyHelper = (SurveyHelper) argument;
                surveyId = surveyHelper.getSurveyId();

            }

        }
        try
        {
            returnVal = pjp.proceed();
        }
        catch (Throwable e)
        {
            gtLogger.debug("Unable to use JointPoint :(");
        }
        return returnVal;
    }

    @After("updateDate()")
    public void updateSurveyDateBySurveyId() throws Exception
    {
        if (surveyId != null)
        {
            surveyService.updateSurveyDateBySurveyId(surveyId);
        }
    }
}



回答2:


I'd use an Hibernate interceptor instead, that's what they are for. For example, the entities that need such fields could implement the following interface:

public interface Auditable {
    Date getCreated();
    void setCreated(Date created);
    Date getModified();
    void setModified(Date modified);
}

Then the interceptor always sets the modified field on save, and only sets the created field when it's not already set.




回答3:


Even though you have been asking for a Spring AOP solution to your question, I would like to point out that the same result can be achieved using database triggers, e. g. automatically setting the created timestamp during INSERT operations and the modified timestamp during UPDATE statements.

This may be a good solution, especially if not all your DB calls are going through the AOP-captured logic (e. g. when bypassing your pointcut definition because a method does not fit the pattern or even bypassing the code completely using a standalone SQL client), so that you could enforce the modified timestamp even when somebody updates the entries from a different application.

It would have the drawback that you need to define the triggers on all affected tables, though.




回答4:


It should be possible with Spring AOP using a @Before advice. If you pass an entity to a create method have an advice set the create_date and for an update method the update_date. You may want to consider the following to make your job easier:

  • Have all entities implement a common interface to set create_date and update_date. This allows you to have a common advice without having to resort to reflection.
  • Have a naming convention to identify create and update methods on our DAOs. This will make your point cuts simpler.


来源:https://stackoverflow.com/questions/12330020/spring-aop-for-database-operation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!