Spring + Hibernate JPA Question - database

I'm trying to use Hibernate with JPA/EntityManager to do database activities
Right now I'm getting this error and I have no idea what it means.
Before I had this code and it works fine.
public class JdbcProductDao extends Dao implements ProductDao {
/** Logger for this class and subclasses */
protected final Log logger = LogFactory.getLog(getClass());
public List<Product> getProductList() {
logger.info("Getting products!");
List<Product> products = getSimpleJdbcTemplate().query(
"select id, description, price from products",
new ProductMapper());
return products;
}
public void saveProduct(Product prod) {
logger.info("Saving product: " + prod.getDescription());
int count = getSimpleJdbcTemplate().update(
"update products set description = :description, price = :price where id = :id",
new MapSqlParameterSource().addValue("description", prod.getDescription())
.addValue("price", prod.getPrice())
.addValue("id", prod.getId()));
logger.info("Rows affected: " + count);
}
private static class ProductMapper implements ParameterizedRowMapper<Product> {
public Product mapRow(ResultSet rs, int rowNum) throws SQLException {
Product prod = new Product();
prod.setId(rs.getInt("id"));
prod.setDescription(rs.getString("description"));
prod.setPrice(new Double(rs.getDouble("price")));
return prod;
}
}
}
But this code using EntityManager
public class JdbcProductDao implements ProductDao {
/** Logger for this class and subclasses */
//protected final Log logger = LogFactory.getLog(getClass());
#PersistenceContext()
private EntityManager entityManager;
public JdbcProductDao(){
}
public Product getReference(Product product){
return getEntityManager().getReference(product.getClass(),product.getId());
}
public void persist(Product product){
getEntityManager().persist(product);
}
public EntityManager getEntityManager(){
return entityManager;
}
public void setEntityManager(EntityManager entityManager){
this.entityManager = entityManager;
}
#SuppressWarnings("unchecked")
public List<Product> getProductList(){
return getEntityManager().createNativeQuery("select id, description, price from products").getResultList();
}
public void saveProduct(Product product){
getEntityManager().createNativeQuery("update products set description = " + product.getDescription() + " , price = " + product.getPrice() + " where id = " + product.getId());
}
private static class ProductMapper implements ParameterizedRowMapper<Product> {
public Product mapRow(ResultSet rs, int rowNum) throws SQLException {
Product prod = new Product();
prod.setId(rs.getInt("id"));
prod.setDescription(rs.getString("description"));
prod.setPrice(new Double(rs.getDouble("price")));
return prod;
}
}
}
The error I get is "java.lang.NumberFormatException: For input string: "description"
Has anybody experienced something similar to this before?
Edit:
The stack trace is below
java.lang.NumberFormatException: For input string: "description"
java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
java.lang.Integer.parseInt(Integer.java:449)
java.lang.Integer.parseInt(Integer.java:499)
javax.el.ArrayELResolver.coerce(ArrayELResolver.java:153)
javax.el.ArrayELResolver.getValue(ArrayELResolver.java:45)
javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54)
org.apache.el.parser.AstValue.getValue(AstValue.java:118)
org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:935)
org.apache.jsp.WEB_002dINF.jsp.hello_jsp._jspx_meth_c_005fout_005f1(hello_jsp.java:245)
org.apache.jsp.WEB_002dINF.jsp.hello_jsp._jspx_meth_c_005fforEach_005f0(hello_jsp.java:210)
org.apache.jsp.WEB_002dINF.jsp.hello_jsp._jspService(hello_jsp.java:92)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:236)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:257)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1183)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:902)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

Look at the stacktrace - there is nothing to do with JPA, you have EL syntax error in the attributes of <c:out> tag in you JSP.

Related

How do I delete multiple records using REST API

Am new to Springboot, I have develop the resource to delete the record by ID, now I like delete selected multiple records.
Example: I like to delete 3 records out of 10 records in single request
Controller class:
#ApiHeader(
apiOperation = "delete a Content Manage by id",
apiOperationNotes = "delete a Content Manage by id"
)
#PostMapping(value = UriConstants.CONTENT_MANAGE_DELETE)
#ResponseStatus(HttpStatus.OK)
public void deleteContentManage(#PathVariable("content_manage_id") int contentmanageId) {
contentManageService.deleteContentManage(contentmanageId);
}
Service Class:
#Transactional(rollbackFor = Exception.class)
public void deleteContentManage(int contentmanageId) {
Optional<UserContentManage> optional = userContentManageRepository.findById(contentmanageId);
if(!optional.isPresent()){
log.error("Exception occurs while not found content manage ({}) in deletion. ", contentmanageId);
throw new GenericBadException(StaffNotificationExceptionEnum.CONTENT_MANAGE_NOT_FOUND_EXCEPTION);
}
userContentManageRepository.deleteById(contentmanageId);
}
JPA Class:
public interface UserContentManageRepository extends JpaRepository<UserContentManage, Integer> {
}
please suggest me how do I delete selected multiple records.
You can add method in Repository like
#Modifying
#Transactional
#Query("delete from UserContentManagep where u.id in(:integers)")
void deleteByIdIn(List<Integer> integers);
If you have implemented soft delete in project you can do soft delete like below:
#Modifying
#Transactional
#Query("update UserContentManagep u set u.active = false where u.id in(:integers)")
void softDeleteAllIds(List<Integer> integers);
And from service class you can try to call as
public void deleteAllBYIds(List<Integer> integers) {
personRepository.deleteByIdIn(integers);
}
Fully working example:
#RestController
#RequestMapping("/person")
public class PersonController {
private final PersonService personService;
#Autowired
public PersonController(PersonService personService) {
this.personService = personService;
}
#GetMapping
public Iterable<Person> list() {
return personService.list();
}
#PostMapping
public Person create(#RequestBody Person car) {
return personService.save(car);
}
#DeleteMapping
public String delete(#RequestParam("ids") List<Integer> ids) {
System.out.println("deleting");
personService.deleteAllBYIds(ids);
return String.join(",", ids.stream().map(value -> Integer.toString(value)).collect(Collectors.toList()));
}
}
#Getter
#Setter
#ToString
#Entity
#Where(clause = "active = true") // selecting only items which are active
class Person {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
private boolean active = true;
}
#Service
class PersonService {
private final PersonRepository personRepository;
#Autowired
PersonService(PersonRepository personRepository) {
this.personRepository = personRepository;
}
#Transactional
public Person save(Person person) {
return personRepository.save(person);
}
#Transactional(readOnly = true)
public Iterable<Person> list() {
return personRepository.findAll();
}
#Transactional(readOnly = true)
public PersonDTO findPersonByName(String name) {
return personRepository.findPersonsByName(name);
}
public void deleteAllBYIds(List<Integer> integers) {
// personRepository.deleteByIdIn(new ArrayList<>(integers));
personRepository.softDeleteAllIds(integers);
System.out.println("deleted adnlakdjakldlas");
}
}
interface PersonDTO {
String getName();
Collection<String> getPersonEvents();
}
#Repository
interface PersonRepository extends CrudRepository<Person, Integer> {
PersonDTO findPersonsByName(String name);
#Modifying
#Transactional
#Query("delete from Person p where p.id in(:integers)")
void deleteByIdIn(List<Integer> integers);
#Modifying
#Transactional
#Query("update Person p set p.active = false where p.id in(:integers)")
void softDeleteAllIds(List<Integer> integers);
}
First of all you need to create a jpa query method that brings all records belong to id.
public interface UserContentManageRepository extends JpaRepository<UserContentManage, Integer> {
List<UserContentManage> findAllById(Integer id);
}
After that you can do deleteAll() operation on List.
#Transactional(rollbackFor = Exception.class)
public void deleteContentManage(int contentmanageId) {
List<UserContentManage> userContentManageList = userContentManageRepository.findAllById(contentmanageId);
if(userContentManageList == null){
log.error("Exception occurs while not found content manage ({}) in deletion. ");
throw new GenericBadException(StaffNotificationExceptionEnum.CONTENT_MANAGE_NOT_FOUND_EXCEPTION);
}
userContentManageRepository.deleteAll(userContentManageList );
}

Hibernate filters are not working for APIs returning single result

I have added Hibernate filters on my entities . These filters are applied on queries which fetch Collection of entity but not applied on queries which fetch single entity. Below is my code.
AOrganization.java
#MappedSuperclass
#FilterDef(name = "OrgFilter", parameters = { #ParamDef(name = "allowedOrgIdList", type = "long") })
#Filter(name = "OrgFilter", condition = "org_id in (:allowedOrgIdList)")
public class AOrganization implements Serializable {
#ManyToOne()
#JoinColumn(name = "org_id", nullable = true)
private Organization organization;
public Organization getOrganization() {
return organization;
}
public void setOrganization(Organization organization) {
this.organization = organization;
}
}
Site.java
#Data
#Entity
#Table(name = "site")
public class Site extends AOrganization{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private long id;
#Column(name = "site_name")
private String siteName;
#Override
public String toString() {
return "Site [id=" + id + ", siteName=" + siteName + "]";
}
}
SiteService.java
public interface SiteService {
public List<Site> getAllSites();
public List<Site> getSiteBySiteName(String siteName);
public Site updateSiteName(Long id, String siteName);
}
SiteRepository.java
#Repository
public interface SiteRepository extends AOrganizationRepository<Site, Long> {
public List<Site> findBySiteName(String siteName);
public List<Site> findByOrganization_Id(Long orgId);
}
AOrganizationRepository.java
#NoRepositoryBean
public interface AOrganizationRepository<T, ID extends java.io.Serializable> extends CrudRepository<T, ID> {
}
SiteServiceImpl.java
#Service
public class SiteServiceImpl implements SiteService {
#Autowired
private EntityManager entityManager;
#Autowired
private SiteRepository siteRepository;
#Override
public List<Site> getAllSites() {
Iterable<Site> sites = siteRepository.findAll();
List<Site> allSites = new ArrayList<>();
sites.forEach(allSites::add);
return allSites;
}
#Override
public List<Site> getSiteBySiteName(String siteName) {
List<Site> allSites = siteRepository.findBySiteName(siteName);
return allSites;
}
#Override
public Site updateSiteName(Long id,String siteName) {
Site site = siteRepository.findById(id).get();
if(site == null)
return null;
site.setSiteName(siteName);
siteRepository.save(site);
return site;
}
}
AOrganizationAspect.java
#Aspect
#Component
#Slf4j
public class AOrganizationAspect {
#PersistenceContext
private EntityManager entityManager;
#Pointcut("execution(public * com.harshal.springboot.springfilter.repository.AOrganizationRepository+.*(..))")
protected void aOrganizationRepositoryRepositoryMethod() {
log.info("aOrganizationRepositoryRepositoryMethod");
}
#Around(value = "aOrganizationRepositoryRepositoryMethod()")
public Object enableOwnerFilter(ProceedingJoinPoint joinPoint) throws Throwable {
// Variable holding the session
Session session = null;
try {
// Get the Session from the entityManager in current persistence context
session = entityManager.unwrap(Session.class);
// Enable the filter
Filter filter = session.enableFilter("OrgFilter");
// Set the parameter from the session
List<Long> orgList = getAllowedOrgIdList();
filter.setParameterList("allowedOrgIdList", orgList);
} catch (Exception ex) {
// Log the error
log.error("Error enabling OrgFilter : Reason -" + ex.getMessage());
}
// Proceed with the joint point
Object obj = joinPoint.proceed();
// If session was available
if (session != null) {
// Disable the filter
session.disableFilter("OrgFilter");
}
// Return
return obj;
}
private List<Long> getAllowedOrgIdList() {
return Arrays.asList(2l);
}
}
So , hibernate filters are applied if method getSiteBySiteName is called and filters are not applied if findById method is called.
Below are queries :
For getSiteBySiteName :
select site0_.id as id1_2_, site0_.org_id as org_id3_2_,
site0_.site_name as site_nam2_2_ from site site0_ where site0_.org_id
in (?) and site0_.site_name=?
Please help . Thanks in advance.
For findById
select site0_.id as id1_2_0_, site0_.org_id as org_id3_2_0_,
site0_.site_name as site_nam2_2_0_, organizati1_.id as id1_1_1_,
organizati1_.address as address2_1_1_, organizati1_.org_name as
org_name3_1_1_ from site site0_ left outer join organization
organizati1_ on site0_.org_id=organizati1_.id where site0_.id=?
findById is using the EntityManager.find method and do not create a query.
Plus Hibernate Filters only work on queries.
You should write a query instead of using findById

MappingException: Ambiguous field mapping detected

Using Spring boot 1.5.6.RELEASE.
I have the following mongo document base class:
#Document(collection="validation_commercial")
public abstract class Tier {
#Id
private String id;
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private Date created;
#Field("tran")
private Tran tran;
public Tier() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Tran getTran() {
return tran;
}
public void setTran(Tran tran) {
this.tran = tran;
}
}
which is then extended:
public class Tier1 extends Tier {
#Field("tier1")
private Tier1Programs tier1;
public Tier1() {
this.tier1 = new Tier1Programs();
}
public Tier1Programs getTier1() {
return tier1;
}
public void setTier1(Tier1Programs tier1) {
this.tier1 = tier1;
}
}
which in turn is extended:
public class Tier2 extends Tier1 {
#Field("tier2")
private Tier2Programs tier2;
public Tier2() {
this.tier2 = new Tier2Programs();
}
public Tier2Programs getTier2() {
return tier2;
}
public void setTier2(Tier2Programs tier2) {
this.tier2 = tier2;
}
}
There is a Tier1 Supervisor (Spring Boot Application) that uses the Tier1 class within the MongoRepository interface:
public interface Tier1Repository extends MongoRepository<Tier1,String>{}
for retrieving and saving - no issue.
I then have a Tier2 Supervisor (Spring Boot Application) that uses a Tier1 Repository (for retrieving the Tier1 document and a Tier2 Repository for saving the Tier2 document:
#Repository("tier1Repository")
public interface Tier1Repository extends MongoRepository<Tier1,String>{}
#Repository("tier2Repository")
public interface Tier2Repository extends MongoRepository<Tier2,String>{}
My service is:
#Service
public class TierService {
#Qualifier("tier1Repository")
#Autowired
private final Tier1Repository tier1Repository;
#Qualifier("tier2Repository")
#Autowired
private final Tier2Repository tier2Repository;
public TierService(#Qualifier("tier1Repository") Tier1Repository tier1Repository, #Qualifier("tier2Repository") Tier2Repository tier2Repository) {
this.tier1Repository = tier1Repository;
this.tier2Repository = tier2Repository;
}
public Tier1 findOne(String id) {
return tier1Repository.findOne(id);
}
public void SaveTier(Tier2 tier) {
tier2Repository.save(tier);
}
public Tier1Repository getTier1Repository() {
return tier1Repository;
}
public Tier2Repository getTier2Repository() {
return tier2Repository;
}
}
and finally the app:
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class})
#Configuration
#ComponentScan(basePackages = {"com.k12commercial.tier2supervisor"})
#ImportResource("classpath:application-context.xml")
public class Application implements CommandLineRunner {
#Autowired
private IReceiver raBidNetPriceReceiver;
#Autowired
private UdyDataSourceFactory udyDSRegistry;
public static void main(String[] args) throws InterruptedException {
try {
SpringApplication.run(Application.class, args);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void run(String... args) throws Exception {
raBidNetPriceReceiver.processTierMessages();
exit(0);
}
}
When I run the Tier2 Supervisor from the command line I get the following error:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'tierService' defined in URL
[jar:file:/opt/java-commandline/tier2supervisor-1.0.jar!/BOOT-INF/classes!/com/k12commercial/tier2supervisor/service/TierService.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tier2Repository': Invocation of init method failed; nested exception is org.springframework.data.mapping.model.MappingException: Ambiguous field mapping detected! Both private final java.lang.reflect.Type org.springframework.data.util.TypeDiscoverer.type and private final java.lang.Class org.springframework.data.util.ClassTypeInformation.type map to the same field name type! Disambiguate using #Field annotation!
I am not sure if the issue is Tier2 extending Tier1 (did try putting #Document tag above Tier1 and Tier2 with no change). I think I have marked the relevant fields so don't understand the need to disambiguate. I thought the issue was having 2 repositories (Spring Boot not knowing which one to DI) so removed the Tier1Repository - didn't work. Tried better qualifying the repositories but still got the same error. I made Tier1 and Tier2 #Transient and that got rid of the message but also removed the tier1 section in the mongo document - so wrong correction.
Thinking it is an annotation fix but not seeing it...
Please advise - thank you.
Sorry for the delay (I got pulled away to work on something else) and thank you to those who responded.
The issue was I had a MongoTemplate in my Tier level programs e.g.Tier2Programs (sub library) which Spring Boot was trying to autowire.
By moving the Mongo (CRUD) requirements to the supervisor level (I also replaced the Repositories with one MongoTemplate to simplify) I removed the ambiguity. (I also removed the Service class).
The code is contained with the RaBidNetReciever class
#Component
public class RaBidNetPriceReceiver extends BaseReceiver implements IReceiver, ApplicationEventPublisherAware {
private static final Logger LOGGER = LoggerFactory.getLogger(RaBidNetPriceReceiver.class);
private final RabbitTemplate raBidNetPriceRabbitTemplate;
public RaBidNetPriceReceiver(MongoTemplate mongoTemplate, RabbitTemplate raBidNetPriceRabbitTemplate) {
super(mongoTemplate);
this.raBidNetPriceRabbitTemplate = raBidNetPriceRabbitTemplate;
}
#Transactional
public void processTierMessages() {
try {
while (true) {
gson = getGsonBuilder().create();
byte[] body = (byte[]) raBidNetPriceRabbitTemplate.receiveAndConvert();
if (body == null) {
setFinished(true);
break;
}
tier1Message = gson.fromJson(new String(body), Tier1Message.class);
// document a 'Tier1' type so retrieve Tier1 first...
Tier1 tier1 = mongoTemplate.findById(tier1Message.getId(), Tier1.class);
Tier2Message tier2Message = new Tier2Message(tier1Message.getTran(), tier1Message.getId());
Tier2Process tierProcess = getTierProcess(tier2Message.getTran().getK12ArchitectureId());
Tier2 tier2 = new Tier2();
tier2.setId(tier1.getId());
tier2.setTier1Programs(tier1.getTier1Programs());
tier2.setCreated(tier1.getCreated());
tier2.setTran(tier1.getTran());
tierProcess.setTier(tier2);
tier2 = tier2.getTier2Programs().getRaBidNetPriceProgram().process(tierProcess);
mongoTemplate.save(tier2);
if (tier2.getTier2Programs().getRaBidNetPriceProgram().isFinished()) {
// publish event
publisher.publishEvent(new ProgramEvent(this, "FINISHED", tier2Message));
}
}
} catch (Exception e) {
LOGGER.error("id: " + tier1Message.getId() + " " + e.getMessage());
}
}
#Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
}
Thank you,

How to delete entity by Id from data-store in AppEngine?

I created an API to delete an Entity by its key however I'm gettin Http 204 and Entity does not delete from data-store.
This is my API,
#ApiMethod(name = "deleteContact", path = "contact", httpMethod = ApiMethod.HttpMethod.DELETE)
public void deleteContact(final #Named("id") long contactId)
{
ofy().delete().type(Contact.class).id(contactId).now();
}
and my Contact class is like this:
#Entity
#Cache
public class Contact
{
#Id
private long id;
#Index
private String cName;
private Email cEmail;
private PhoneNumber cPhoneNumber;
// private key, to connect this Entity to Profile Entity
#Parent
#ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
private Key<Profile> profileKey;
#ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
private String profileId;
// default constructor is private
private Contact()
{
}
public Contact(final long id, final String profileId, final ContactForm contactForm)
{
Preconditions.checkNotNull(contactForm.getUserName(), "The name is required");
this.id = id;
this.profileKey = Key.create(Profile.class, profileId);
this.profileId = profileId;
updateWithContactForm(contactForm);
}
/**
* Updates the Contact with ContactForm.
* This method is used upon object creation as well as updating existing Contact.
*
* #param contactForm contains form data sent from the client.
*/
public void updateWithContactForm(final ContactForm contactForm)
{
this.cName = contactForm.getUserName();
this.cEmail = contactForm.getUserEmailAddress();
this.cPhoneNumber = contactForm.getUserPhoneNumber();
}
public long getId() {
return id;
}
public String getcName() {
return cName;
}
public Email getcEmail() {
return cEmail;
}
public PhoneNumber getcPhoneNumber() {
return cPhoneNumber;
}
#ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
public Key<Profile> getProfileKey() {
return profileKey;
}
// Get a String version of the key
public String getWebSafeKey()
{
return Key.create(profileKey, Contact.class, id).getString();
}
#ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
public String getProfileId() {
return profileId;
}
#Override
public String toString() {
return "Contact{" +
"id=" + id +
", cName='" + cName + '\'' +
", cEmail=" + cEmail +
", profileId='" + profileId + '\'' +
", cPhoneNumber=" + cPhoneNumber +
'}';
}
}
Any idea would be appreciated.
You've got a parent associated with your class Contact.
// private key, to connect this Entity to Profile Entity
#Parent
#ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
private Key<Profile> profileKey;
In datastore, Contact entities are stored as:
/User1Profile/SomeContact1
/User1Profile/SomeContact2
Datastore can't search any entity with just the ID of contact (i.e. "SomeContact1") but it can search if you provide parent as well. The right way to delete would be:
ofy().delete().type(Contact.class).parent(profileKey).ids(contactId).now();
Read this for more details: https://code.google.com/p/objectify-appengine/wiki/BasicOperations#Deleting

Spring AOP with Struts2 Action

I tried to apply AOP to Struts2 action classes.
My configurations are:
<aop:aspectj-autoproxy proxy-target-class="true"/>
<bean id="actionClassAspect" class="com.rpm.application.profiling.ActionClassAspect"/>
<aop:config>
<aop:pointcut id="actionClassPointcut" expression="execution(public * com.rpm..action.*.*(..))
and !execution(public * com.rpm..action.*.get*(..))
and !execution(public * com.rpm..action.*.set*(..))
and !within(com.rpm..profiling.*)"/>
<aop:aspect id="actionAspect" ref="actionClassAspect">
<aop:around method="doAspect" pointcut-ref="actionClassPointcut"/>
</aop:aspect>
my action class is:
package com.rpm.application.common.web.action;
import com.opensymphony.xwork2.ActionSupport;
public class ApplicationLoginAction extends ActionSupport {
private String userID, password;
#Override
public String execute() throws Exception {
try {
//validation logic
System.out.println("Login success");
return SUCCESS;
} catch(Exception e) {
return ERROR;
}
}
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
my aspect is:
package com.rpm.application.profiling;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
#Aspect
public abstract class ActionClassAspect {
public Object doAspect(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object returnValue = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
long end = System.currentTimeMillis();
System.out.println(" " + proceedingJoinPoint.getTarget().getClass() + " KIND:" + proceedingJoinPoint.getSignature().toShortString() + " TIME: " + (end - start));
return returnValue;
}
}
When I executing this application on tomcat6.x server AOP is not applied to that action class.
I found the solution. Need to add struts2-spring-plugin-2.x.x.jar in classpath.
This plug-in will add automatically all action classes configured in struts.xml into spring container.

Resources