My spring boot application have behaved pretty well until I needed to access two services from the controller. In the method CreateCompany I want to check that the user exists before I store the company in the db. The company data is received properly, as is the adminId path variable.
This works once, but if I want to insert another company for the same user, I get a ClassCastException for when I try to look up the user.
A weird thing though, is that I in a different class is using the CompanyTagService to successfully insert tags into a database. When debugging, it appears as a CompanyTagService object, while the CompanyService and UserService are proxies. This is suspicious to me, but I know to little about spring proxies to figure out anything useful from it.
What am I doing wrong?
CompanyServiceBean.java
@RestController
@RequestMapping( value="/api/company")
public class CompanyController {
@Value( "${application.config.logo_folder}" )
private String logoFolder;
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private CompanyService service;
@Autowired
private CompanyTagService tagService;
@Autowired
private UserService uService;
@RequestMapping(
value="/admin/{adminId}",
method=RequestMethod.POST,
consumes=MediaType.APPLICATION_JSON_VALUE,
produces=MediaType.APPLICATION_JSON_VALUE )
public ResponseEntity< ? > CreateCompany( @RequestBody Company company, @PathVariable( "adminId") Long adminId ){
Company ret = null;
ResponseEntity< ? > resp = null;
User u = uService.findOne( adminId ); //This is where the exception occurrs.
if( null != u )
logger.info( "User {} was found.", u.getFirstName() );
logger.info( "Creating company record for admin with id {}", adminId);
if( u == null ){
resp = new ResponseEntity< RestResult >( new RestResult( "The user id must be set", HttpStatus.BAD_REQUEST ), HttpStatus.BAD_REQUEST );
}
else {
company.setAdminId(adminId);
try{
ret = service.create( company );
resp = new ResponseEntity< Company >( ret, HttpStatus.CREATED );
}
catch( DataIntegrityViolationException ie ){
resp = new ResponseEntity< RestResult >( new RestResult( "Company name or org. no. was already in use", HttpStatus.BAD_REQUEST ), HttpStatus.BAD_REQUEST);
}
catch( Exception e ){
resp = new ResponseEntity< RestResult >( new RestResult( "Could not create the company.", HttpStatus.INTERNAL_SERVER_ERROR ), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
return( resp );
}
... Other service methods
UserServiceBean.java:
@Service
@Transactional( propagation = Propagation.SUPPORTS, readOnly = true )
public class UserServiceBean implements UserService {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private UserRepository userRepo;
@Override
@CachePut( value="EntWeb", key="#result.id" )
@Transactional( propagation = Propagation.REQUIRED, readOnly = false )
public User create(User user) {
User ret = null;
if( user.getId() == null ) {
ret = userRepo.save( user );
}
return( ret );
}
@Override
@Cacheable( value="EntWeb", key="#id")
public User findOne(Long id) {
User ret = userRepo.findOne( id );
return( ret );
}
... Other Service methods
The error output
java.lang.ClassCastException: org.entweb.model.Company cannot be cast to org.entweb.model.User
at com.sun.proxy.$Proxy126.findOne(Unknown Source) ~[na:na]
at org.entweb.web.api.CompanyController.CreateCompany(CompanyController.java:58) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_77]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_77]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_77]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_77]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
The only problem comes to (my) mind is cache. Namely - putting different objects into one cache. Peter confirmed that it is the problem.
To fix that... There are two ways:
To have it done, look at cachePut spec. Values property is the one you are using to tell which caches should be updated, and contain this particular result object. Most projects uses dot prefixes - EntWeb.users.admins
- or maybe entweb.users
is enough. Beauty is that you can later change it.
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.