I am new to Spring Jpa and Hibernate. I am trying to fetch data using a custom function from an Oracle db. I could define an entity along with its related service, implementation and repository. In addition, I created a new custom Oracle dialect by using registerFunction as you will see below.
So I have two questions:
1) In my Oracle db, the function sits under a different schema. Do I need to specify its schema? If so how? Or will hibernate find it automatically?
I will be asking my second question at the end of this post after providing my full stacktrace...
Here is my full stack trace:
MyOracle10gDialect
package blog;
import org.hibernate.dialect.Oracle10gDialect;
import org.hibernate.dialect.function.StandardSQLFunction;
public class MyOracle10gDialect extends Oracle10gDialect {
public MyOracle10gDialect() {
super();
registerFunction("my_function", new StandardSQLFunction("my_function"));
}
}
application.properties
...
spring.jpa.database-platform=blog.MyOracle10gDialect
...
Entity:
package blog.models;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "item", schema = "WOS_SOURCE")
public class WosItem {
#Id
#Column(nullable = false)
private String UT;
#Column(nullable = false)
private String TI;
public String getUT() {
return UT;
}
public void setUT(String UT) {
this.UT = UT;
}
public String getTI() {
return TI;
}
public void setTI(String TI) {
this.TI = TI;
}
public WosItem(String UT, String TI) {
this.UT = UT;
this.TI = TI;
}
public WosItem() { }
#Override
public String toString() {
return "WosItem{" +
"UT='" + UT + '\'' +
", TI='" + TI + '\'' +
'}';
}
}
Service:
package blog.services;
import blog.models.WosItem;
import org.springframework.stereotype.Service;
import java.util.List;
#Service
public interface WosItemService {
List<WosItem> findAll();
WosItem findById(String id);
String find_ut(Long ut_seq);
}
Implementation:
package blog.services;
import blog.models.WosItem;
import blog.repositories.WosItemRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
#Service
public class WosItemServiceJpaImpl implements WosItemService {
#Autowired
private WosItemRepository wosItemRepository;
#Override
public List<WosItem> findAll() {
return this.wosItemRepository.findAll();
}
#Override
public WosItem findById(String id) {
return this.wosItemRepository.findOne(id);
}
#Override
public String find_ut(Long ut_seq) {
return this.wosItemRepository.find_ut();
}
}
Repository:
package blog.repositories;
import blog.models.WosItem;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
#Repository
public interface WosItemRepository extends JpaRepository<WosItem, String> {
#Query("SELECT function('my_function', input) FROM WosItem wos");
String find_ut();
}
So in my Oracle db I can use this function as shown below:
select other_schema.my_function(aa.input) from my_schema.TABLE aa;
For ex. say aa.input is 332708100009 then it returns 000332708100009
As for my second question:
2) How can I carry out this process in jpa? I am aware that my repository is not correct at all. I get an error like "Annotations are not allowed here". I could not find a way to remedy this.
Thanks in advance.
EDIT ON THROWN EXCEPTION:
Caused by: java.lang.IllegalStateException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode
\-[METHOD_CALL] MethodNode: 'function (my_function)'
+-[METHOD_NAME] IdentNode: 'my_function' {originalText=my_function}
\-[EXPR_LIST] SqlNode: 'exprList'
\-[NAMED_PARAM] ParameterNode: '?' {name=ut_seq, expectedType=null}
Unfortunately if you want to use the JPA 2.1 feature of the custom function call in your Select statement then you will need to perform some additional actions before you can use it.
When you use it in your where statement then it works without any additional actions, but as i wanted to use it for one of my projects inside the select just as you did then you would need to:
1) Extend the hibernate dialect and register your function(s):
package com.mypkg.dialect;
import org.hibernate.dialect.Oracle10gDialect;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.type.StringType;
public class CustomOracle10gDialect extends Oracle10gDialect {
public CustomOracle10gDialect() {
super();
registerFunction("my_function"
, new StandardSQLFunction("my_function", new StringType()));
}
}
2) Edit your hibernate.dialect property of your session factory to point to that custom implementation:
<property name="hibernate.dialect" value="com.mypkg.dialect.CustomOracle10gDialect"/>
Update
If the function needs to be called from a certain schema then this would be suggested:
registerFunction("my_function"
, new StandardSQLFunction("schema.my_function", new StringType()));
Further reading -> native function calls
Related
Lets assume we have one table/View with below columns
columns : ID , Status
I am writing one search API to get Data from backend
I am using org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
.....
#Repository
#Transactional
public interface UIDashboard extends JpaRepository<UIDashboardView, String> {
....
#Query(value = "SELECT results from SearchView results where "
+ "(:status is null or results.STATUS = :status) and"
+ "(coalesce(:ids) is null or results.ID in :ids)"
...
My DTO
import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import java.util.Optional;
import lombok.Data;
#Data
#JsonInclude(Include.NON_NULL)
public class SearchInputDTO {
#JsonProperty(value="status",required = false)
private String status;
#JsonProperty(value="ids",required = false)
//private Optional<List<String>> ids;
//ArrayList<String> ids;
private List<String> ids;
REST API
import org.springframework.web.bind.annotation.PostMapping;
...
#PostMapping("/searchTest")
public ResponseEntity<List<ResultsDTO>> search_test(
#RequestBody #NotNull #Valid SearchInputDTO payload, HttpServletRequest request)
throws IOException {
}
{
"status" : "COMPLETED",
"ids" : [null,null]
}
Issue with the approach is to invoke POST REST API i need to send two null values [null,null] in payload i,e without id's property i am unable to execute POST API , so either i need to send null values or set in DTO.
I also tried to make Optional in DTO or
Used coalesce -> (coalesce(:ids) is null or results.ID in :ids)
i dont want to explicitly send null values in Payload , User can search with any parameter for example only with one property :status:
{
"status" : "INPROCESS"
}
Above payload not working as i am not sending "ids"
Then i tried set nulls in setter as workaround
#JsonProperty(value="ids",required = false)
private List<String> ids = new ArrayList<>(Arrays.asList(null, null));
#JsonSetter("ids")
public void setIds(List<String> li){
if (li != null) {
if (li.size() < 2){
li.add(null);
li.add(null);
this.ids = li;
}
else{
this.ids = li;
}
}
}
I dont like this work around , is there any better solution or changes required to JPQL IN parameter or SearchInputDTO .
I also followed blog Spring Data repository with empty IN clause
Thanks,
Showkath.
I would like to turn off deserialization for concrete enum. Is it possible?
Exercise model class:
package main.exercise;
import lombok.*;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Entity
#Builder
public class Exercise {
#Id
#GeneratedValue
private int id;
#NonNull
private String name;
#NonNull
private ExerciseType exerciseType;
private double caloriesBurned;
private String exerciseDescription;
}
I got method in controller:
#PostMapping("/addExercise")
public List<String> addExercise(#RequestBody Exercise exercise) {
return exerciseCrudActivitiesService.addExercise(exercise);
}
which takes Exercise body and if type of Exercise is wrong I got error while POST http request:
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `main.exercise.ExerciseType` from String "CARdDIO": not one of the values accepted for Enum class: [CARDIO, WEIGHTLIFTING]; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `main.exercise.ExerciseType` from String "CARdDIO": not one of the values accepted for Enum class: [CARDIO, WEIGHTLIFTING]
at [Source: (PushbackInputStream); line: 4, column: 25] (through reference chain: main.exercise.Exercise["exerciseType"])]
The point is in service I got validator, which validates whether type of enum is right or wrong and return string to list of errors from all validators. Unfortunately this code cannot be reached because of error.
public List<String> addExercise(Exercise exercise) {
ExerciseValidator validator = new ExerciseValidator();
List<String> messages = validator.validate(exercise);
if (messages.isEmpty()) {
exerciseRepository.save(exercise);
}
return messages;
}
Validator
package main.exercise.validator.attributesvalidators;
import main.exercise.Exercise;
import main.exercise.ExerciseType;
import main.exercise.validator.ExerciseAttributesValidator;
import java.util.InputMismatchException;
public class ExerciseTypeValidator implements ExerciseAttributesValidator {
#Override
public String validate(Exercise exercise) {
if (exercise.getExerciseType() == null) {
return "You didn't put exercise type!";
}
try {
ExerciseType.forName(exercise.getExerciseType().name());
} catch (InputMismatchException e) {
return "Wrong exercise type!";
}
return null;
}
}
To turn off (de-)serialization, you can add the #JsonIgnore to the exerciseType field. However, I don't think this will help you anyways.
If serialization is ignored, the field would always be null which is not the intended behavior.
Your validator is too late. Note: the validate method takes an Exercise object as a parameter. The problem occurs during the creation of this object already.
When you get to the point that the line ExerciseType.forName(exercise.getExerciseType().name()); get's executed, it will NEVER throw an exception, because getExerciseType() is already a valid enum.
Instead of this custom validator, you could make use of a Spring #ControllerAdvice to register your own Exception handler for that error type.
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import com.fasterxml.jackson.databind.exc.InvalidFormatException
#ControllerAdvice
public class GlobalExceptionHandler {
#ExceptionHandler(InvalidFormatException.class)
public ResponseEntity<?> badFormatException(InvalidFormatException ex, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
}
}
See e.g. https://www.springboottutorial.com/spring-boot-exception-handling-for-rest-services for more details.
I am implementing a Rest WS using Spring 4 (Spring Boot).
The basic idea is I want to consume a JSON payload specifying an identifier (e.g. social security number or something) and run multiple subServices on that identifier.
Here is a sample payload:
{
"ssNumber" : "1111111111111111",
"subServicesDetails" :
[
{ "subServiceName" : "Foo" , "requestParameters" : {} },
{ "subServiceName" : "Dummy", "requestParameters" : {} }
]
}
In my code I have multiple "sub-services" (FooService, DummyService) implementing the SubService interface:
package com.johnarnold.myws.service;
import com.johnarnold.myws.model.SubServiceDetails;
public interface SubService {
public boolean service(String ssNumber, SubServiceDetails ssd);
}
And below is the FooService code.
package com.johnarnold.myws.service;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.johnarnold.myws.dao.FooDao;
import com.johnarnold.myws.model.Foo;
import com.johnarnold.myws.model.SubServiceDetails;
#Component
public class FooService implements SubService{
private static Logger log = Logger.getLogger(FooService.class);
#Autowired
private FooDao dao;
public FooService()
{
log.debug("FooService ctor");
}
public boolean service(String ssNumber, SubServiceDetails ssd)
{
log.debug("FooService service");
Map <String, String> responseParameters = new HashMap<String, String>();
try
{
Foo foo = dao.getFoo(ssNumber);
if(foo.isCompromised())
{
responseParameters.put("listed", "true");
}
else
{
responseParameters.put("listed", "false");
}
ssd.setResponseParameters(responseParameters);
return true;
}
catch(Throwable ex)
{
log.error("Exception in service ", ex);
}
return false;
}
}
Now I wrote my own factory to create the subservices but when I did that of course because I am explictly creating my beans (e.g. FooService) below - my container is not auomatically injecting any of the #Autowired members - FooDao for example:
package com.johnarnold.myws.service;
public class SubServiceFactory {
/*
* Instantiates a SubService for the supplied subServiceName or throws an exception if
* no valid SubService exists
*/
public static SubService createSubService(String subServiceNameStr)
{
SubService subService = null;
System.out.println("subServiceName [" + subServiceNameStr + "]");
if(subServiceNameStr.equals("Foo"))
{
subService = new FooService();
}
if(subServiceNameStr.equals("Dummy"))
{
subService = new DummyService();
}
else
{
System.out.println("subServiceName [" + subServiceNameStr + "] is not defined");
}
return subService;
}
}
For completeness here is the Controller:
package com.johnarnold.myws.controller;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.apache.log4j.Logger;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.johnarnold.myws.model.RawsPayload;
import com.johnarnold.myws.model.SubServiceDetails;
import com.johnarnold.myws.service.SubService;
import com.johnarnold.myws.service.SubServiceFactory;
import com.johnarnold.myws.web.ValidMessage;
#RestController
#RequestMapping("/raws/")
public class RawsController {
private static final Logger logger = Logger.getLogger(RawsController.class);
//#Autowired
//SubService [] subSvcs;
#RequestMapping(value="/{version}/status", method=RequestMethod.GET)
public ResponseEntity<ValidMessage> getServiceStatus()
{
return new ResponseEntity<>(new ValidMessage() , HttpStatus.OK);
}
/*
* Main entry point - orchestrates all of the WS Sub Services
*/
#RequestMapping(value="/{version}/raws", method=RequestMethod.PUT)
public ResponseEntity<String> raws(#Valid #RequestBody RawsPayload rawsPayload,
HttpServletRequest request)
{
logger.info("Request received");
System.out.println("payl " + rawsPayload);
System.out.println("ssNumber=" + rawsPayload.getSsNumber());
System.out.println("sub svcs details=" + rawsPayload.getSubServicesDetails().length);
SubServiceDetails[] subServiceDetails = rawsPayload.getSubServicesDetails();
for(SubServiceDetails ssd : subServiceDetails)
{
String subServiceNameStr = ssd.getSubServiceName();
System.out.println("svcname=" + subServiceNameStr);
System.out.println("svc req params=" + ssd.getRequestParameters());
System.out.println("svc resp params=" + ssd.getResponseParameters());
SubService subService = SubServiceFactory.createSubService(subServiceNameStr);
// Probably wrap the below with some timings
subService.service(rawsPayload.getSsNumber(), ssd);
}
//System.out.println("svcs are " + subSvcs + "size=" + subSvcs.length);
return new ResponseEntity<>("foo" , HttpStatus.OK);
}
}
And here is the main payload class:
package com.johnarnold.myws.model;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.apache.log4j.Logger;
import org.hibernate.validator.constraints.Length;
public class RawsPayload {
static Logger log = Logger.getLogger(RawsPayload.class);
#NotNull
#Length(min=16, max=19)
private String ssNumber;
#Valid
#NotNull
#Size(min=1, max=3)
private SubServiceDetails [] subServicesDetails;
public String getSsNumber() {
return ssNumber;
}
public void setSsNumber(String ssNumber) {
log.info("setSsNumber()");
this.ssNumber = ssNumber;
}
public SubServiceDetails[] getSubServicesDetails() {
return subServicesDetails;
}
public void setSubServicesDetails(SubServiceDetails[] subServicesDetails) {
this.subServicesDetails = subServicesDetails;
}
}
I've read a number of answers on StackOverflow regarding Spring 4 Conditional Beans - but this functionality appears to be targeted at Context / Configuration type information rather than Request message content (as in this case).
Can anyone point me in the right direction. I can provide further context if necessary
KRgds
John
Two possible ways of solving this problem:
Add all your subService beans to the Spring context then select from them using a ServiceLocatorFactoryBean. This is the nicer approach (from architectural point of view), but it might require a bit more time to implement if you have never used this concept before.
There is a simpler alternative below if you want to stick with basic Spring solutions:
Have the subservice beans injected into your main service as a list, and then select from that. It would look something like this:
#Bean
public List<SubService> subServices(){
List<SubService> list = new SubService<>();
list.add(new AService());
list.add(new BService());
return list;
}
THEN
public SubService selectServiceByName() {
//iterate through the list, pick the service with the right name and return - this solution will require you to bind by beannames
}
#john-arnold First, crate all the services like this, or annotate them with #Service/#Component with explicit names like below: names are start with the values of subServiceName param and contains a common suffix, "Service" here, thats important.
#Bean("FooService")
public SubService fooService() {
return new FooService();
}
#Bean("DummyService")
public SubService dummyService() {
return new DummyService();
}
Then change your factory like this:
#Component
public class SubServiceFactory implements BeanFactoryAware{
private BeanFactory beanFactory;
private static final String MY_SERVICE_SUFFIX = "Service";
#Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
public <T> T getServiceImplementation(String name, Class<T> requiredType) {
return beanFactory.getBean(name + MY_SERVICE_SUFFIX, requiredType);
}
}
Now what we have here is a BeanFactoryAware class that you can inject to your Rest Endpoint and instead of if statement, try this:
subServiceFactory.getServiceImplementation(subServiceNameStr, SubService.class);
This will return your bean or an exception if it doesn't find one. If you don't want an exception, you can catch it and return null or you can create a Service imp. just for these and return that instance. Your choice.
Edit:
As a shortcut, you can define your imp. Beans and than add this to your rest endpoint
#Autowired
private Map<String, SubService> mySubServices;
Spring will automatically inject all your imp. ref. so you can just use get() method of the map. But i prefer the first one..
You don't need anything fancy here. Just implement all your services that implement your service interface, annotate them all with either #Component or #Service and scan them as usual.
Then, wherever you have to choose a concrete service implementation, autowire all implementations of your service like this:
#Autowired
Map<String, SubService> subServices;
The key of the map will be the name of the service as specified in the #Component annotation of every sub service implementation, and the value will be the instance.
So, when you receive you JSON, just get the name of the sub service (i.e. Foo), and get the specific service of the map:
SubService fooSubService = subServices.get(subServiceName + "Service");
where subServiceName is the uncapitalized name of the sub service you're receiving in your JSON (i.e. if you're receiving Foo this would be foo).
The convention is to use the uncapitalized name of the class that implements the interface as the bean name, i.e. for the FooService class the bean name will be fooService, and this is the key you have to look for in the map.
I'm trying to use the Play framework (Java) to simply read some data from a few Oracle tables, probably even use a few complex queries later on. I'm following a tutorial but I'm having some issues retrieving the data.
My Model class look like this:
package models;
import java.util.ArrayList;
import java.util.List;
import play.libs.F;
import javax.persistence.*;
import com.avaje.ebean.*;
import play.db.ebean.*;
#Entity
#Table(name="TABLESPACE.CAT_BONDS")
public class Cat_Bond extends Model {
#Id
public String symbol;
public String database;
public String tickType;
public String assetClass;
public String sourcePlatform;
public String sourceExchange;
public static Finder<String, Cat_Bond> find = new Finder<String, Cat_Bond>(String.class,Cat_Bond.class);
public Cat_Bond(){}
public Cat_Bond(String symbol, String database, String tickType, String assetClass,
String sourcePlatform, String sourceExchange) {
this.symbol = symbol;
this.database = database;
this.tickType = tickType;
this.assetClass = assetClass;
this.sourcePlatform = sourcePlatform;
this.sourceExchange = sourceExchange;
}
/*
* retrieve all rows from the 'cat_bonds' table
*/
public static List<Cat_Bond> findAll(){
//return new ArrayList<Cat_Bond>(cat_bond);
return find.all();
}
/*
* Find by EAN
*/
public static Cat_Bond findByEan(String symbol){
return find.where().eq("symbol", symbol).findUnique();
}
}
My controller class:
package controllers;
import java.util.List;
import views.html.*;
import models.Cat_Bond;
import play.data.Form;
import play.mvc.*;
public class Cat_Bonds extends Controller {
private static final Form<Cat_Bond> cat_bondForm = Form.form(Cat_Bond.class);
public static Result list(){
List<Cat_Bond> cat_bond = Cat_Bond.findAll();
return ok(list.render(cat_bond));
}
And the application.conf entry looks like:
#Oracle
db.default.driver=oracle.jdbc.OracleDriver
db.default.url="jdbc:oracle:thin:#server.uk.net.intra:port/ALIAS"
db.default.user=user
db.default.password=pass
# Evolutions
# ~~~~~
# You can disable evolutions if needed
evolutionplugin=disabled
Problem is when the call to list is made in the controller then to findAll() in the model I get the error:
**[PersistenceException: Query threw SQLException:ORA-00904: "T0"."SOURCE_EXCHANGE": invalid identifier Bind values:[] Query was: select t0.symbol c0, t0.database c1, t0.tick_type c2, t0.asset_class c3, t0.source_platform c4, t0.source_exchange c5 from TABLESPACE.CAT_BONDS t0 ]**
#Column(name="xx")
Was required above each variable defined in the model class that was to be mapped to the table column.
You can use
clean
compile
~run
If it doesn't work properly, you can use #EntityConcurrencyMode(ConcurrencyMode.NONE) within your model class.
public static UserDetail UserDetail.findUserDetail(Long id) {
if (id == null) return null;
return entityManager().find(UserDetail.class, id);
}
We are using spring Roo. Above is Roo generated finder method. Partial stack trace is as follows:
Caused by: org.hibernate.WrongClassException: Object with id: 1501237 was not of the specified subclass: com.***.***.user.UserDetail (Discriminator: FacebookUserDetail)
Has anyone come across this exception?
EDIT
This question and following questions are related to same issue.
Java class file truncated
I have two projects. My one project (say project2) depends on another project(project2). Both projects are maven project and project1 is listed in dependancies of project2. When I compile project2, all the class files from project1 should be copied to project2 (I imagine). But, I see that the file size of one of the class files in project1 is different than file size of class file for the same class in project2. If I decompile the files I get following results.
Decompiled FacebookUserDetail.class from project1:
package com.***.domain.user.external;
import com.***.domain.user.UserDetailType;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.TypedQuery;
import org.aspectj.lang.JoinPoint;
import org.aspectj.runtime.internal.CFlowCounter;
import org.aspectj.runtime.reflect.Factory;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.aspectj.AbstractDependencyInjectionAspect;
import org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect;
import org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl;
#Configurable
#Entity
public class FacebookUserDetail extends ExternalUserDetail
{
public FacebookUserDetail()
{
JoinPoint localJoinPoint = Factory.makeJP(ajc$tjp_1, this, this); if ((!AnnotationBeanConfigurerAspect.ajc$if$bb0((Configurable)getClass().getAnnotation(Configurable.class))) && (AbstractDependencyInjectionAspect.ajc$if$6f1(localJoinPoint))) AnnotationBeanConfigurerAspect.aspectOf().ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(this);
}
public static FacebookUserDetail findFacebookUserDetailByFacebookId(String facebookId)
{
String str = facebookId; JoinPoint localJoinPoint = Factory.makeJP(ajc$tjp_0, null, null, str); if ((AnnotationDrivenStaticEntityMockingControl.ajc$cflowCounter$1.isValid()) && (AnnotationDrivenStaticEntityMockingControl.hasAspect())) return (FacebookUserDetail)findFacebookUserDetailByFacebookId_aroundBody1$advice(str, localJoinPoint, AnnotationDrivenStaticEntityMockingControl.aspectOf(), null, ajc$tjp_0, localJoinPoint); return findFacebookUserDetailByFacebookId_aroundBody0(str, localJoinPoint);
}
public UserDetailType getExternalUserDetailType()
{
return UserDetailType.FACEBOOK;
}
static
{
ajc$preClinit(); }
public static long countFacebookUserDetails() { return FacebookUserDetail_Roo_Entity.ajc$interMethod$com_nim_domain_user_external_FacebookUserDetail_Roo_Entity$com_nim_domain_user_external_FacebookUserDetail$countFacebookUserDetails(); }
public static List<FacebookUserDetail> findAllFacebookUserDetails() { return FacebookUserDetail_Roo_Entity.ajc$interMethod$com_nim_domain_user_external_FacebookUserDetail_Roo_Entity$com_nim_domain_user_external_FacebookUserDetail$findAllFacebookUserDetails(); }
public static FacebookUserDetail findFacebookUserDetail(Long paramLong) { return FacebookUserDetail_Roo_Entity.ajc$interMethod$com_nim_domain_user_external_FacebookUserDetail_Roo_Entity$com_nim_domain_user_external_FacebookUserDetail$findFacebookUserDetail(paramLong); }
public static List<FacebookUserDetail> findFacebookUserDetailEntries(int paramInt1, int paramInt2) { return FacebookUserDetail_Roo_Entity.ajc$interMethod$com_nim_domain_user_external_FacebookUserDetail_Roo_Entity$com_nim_domain_user_external_FacebookUserDetail$findFacebookUserDetailEntries(paramInt1, paramInt2); }
public static TypedQuery<FacebookUserDetail> findFacebookUserDetailsByUserIdEquals(String paramString) { return FacebookUserDetail_Roo_Finder.ajc$interMethod$com_nim_domain_user_external_FacebookUserDetail_Roo_Finder$com_nim_domain_user_external_FacebookUserDetail$findFacebookUserDetailsByUserIdEquals(paramString); }
public String toString() { return FacebookUserDetail_Roo_ToString.ajc$interMethod$com_nim_domain_user_external_FacebookUserDetail_Roo_ToString$com_nim_domain_user_external_FacebookUserDetail$toString(this); }
}
Decompiled FacebookUserDetail.class from project2
package com.***.domain.user.external;
import com.***.domain.user.UserDetailType;
import org.aspectj.lang.JoinPoint;
import org.aspectj.runtime.internal.CFlowCounter;
import org.aspectj.runtime.reflect.Factory;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.aspectj.AbstractDependencyInjectionAspect;
import org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect;
import org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl;
public class FacebookUserDetail extends ExternalUserDetail
{
public FacebookUserDetail()
{
JoinPoint localJoinPoint = Factory.makeJP(ajc$tjp_1, this, this); if ((!AnnotationBeanConfigurerAspect.ajc$if$bb0((Configurable)getClass().getAnnotation(Configurable.class))) && (AbstractDependencyInjectionAspect.ajc$if$6f1(localJoinPoint))) AnnotationBeanConfigurerAspect.aspectOf().ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(this);
}
public static FacebookUserDetail findFacebookUserDetailByFacebookId(String facebookId)
{
String str = facebookId; JoinPoint localJoinPoint = Factory.makeJP(ajc$tjp_0, null, null, str); if ((AnnotationDrivenStaticEntityMockingControl.ajc$cflowCounter$1.isValid()) && (AnnotationDrivenStaticEntityMockingControl.hasAspect())) return (FacebookUserDetail)findFacebookUserDetailByFacebookId_aroundBody1$advice(str, localJoinPoint, AnnotationDrivenStaticEntityMockingControl.aspectOf(), null, ajc$tjp_0, localJoinPoint); return findFacebookUserDetailByFacebookId_aroundBody0(str, localJoinPoint);
}
public UserDetailType getExternalUserDetailType()
{
return UserDetailType.FACEBOOK;
}
static
{
ajc$preClinit();
}
}
My question is: What are possible reasons for truncated class file in project2?
As far as I understand from the error you have the following scenario:
you request an entity of type UserDetail with that ID (which should have the DTYPE/discriminator column value equal to FacebookUserDetail or other that extend UserDetail), but in your DB the DTYPE is another. You have to correct your DB for that.
Or it could also be, that FacebookUserDetail is not recognized as being a DTYPE of the same hierarchy. Try debugging a bit, e.g testing what is returned if you search for a FacebookUserDetail instance of the same ID.
It looks like your super class and subclasse didn't share the same id in the database for the requested record 1501237
It is obvious you have an inheritance problem, take a look at http://en.wikibooks.org/wiki/Java_Persistence/Inheritance