My case is super weird, and quite frankly I am not entirely sure if its a Jackson serialization problem or something to do with Spring Data JPA on how it fetches Lazy objects
Spring 2.0.2
- spring-boot-starter-data-jpa
- spring-boot-starter-web
- spring-boot-devtools
- mysql-connector-java
When you search most people's problem with Jackson is it serialization a lazy fetch outside a session causing below exception. However, I am not getting this exception at all....
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
Problem
- It actually fetches the data and return json object in my controller (hibernate query below). Its a problem to Fetch Eagerly because its getting unnecessary large data that is not used.
Structure (Omit getter and setter to make the thread shorter)
User
| <---[ OneToMany ]
Employee { hierarchies entity }
|
+-----+-----+
| |
PartTime FullTime
User
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy="user")
@JsonIgnoreProperties("user")
private List<Employee> employee = new ArrayList<>();
Empolyee
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JsonIgnoreProperties("employee")
private User user;
FullTime / PartTime ( field salary change to hourelywage when in PartTime )
@Entity
public class FullTime extends Employee {
private BigDecimal salary;
UserRepository extends CrudRepository
UserService
public User getUserById(Long id) {
Optional<User> optionalUser = userRepo.findById(id);
User user = optionalUser.get();
logger.info("\n User -> {}", user);
return user;
}
Controller
@RestController
@RequestMapping(value="/api/user")
public class UserController {
@GetMapping(value="/{userId}" )
public User getUser(@PathVariable("userId") Long id) {
return userService.getUserById(id);
}
}
On my Application extends CommandLineRunner which allows me to run commands at start of application
@Override
public void run(String... args) throws Exception {
logger.info("users 1 -> {}" , userService.getUserById(1L));
}
Hibernate:
select
user0_.id as id1_3_0_,
user0_.name as name2_3_0_
from
user user0_
where
user0_.id=?
INFO 14434 --- [ restartedMain] ication$$EnhancerBySpringCGLIB$$6cf0457c :
users 1 ->
User [id=1, name=Jack]
But when I go through my controller http://localhost:8080/api/user/1
I get 2 separate hibernate calls both seems to be within my service layer. Keep in mind, my service layer I do not have Transactional, so its really weird....
Hibernate: << 1st
select
user0_.id as id1_3_0_,
user0_.name as name2_3_0_
from
user user0_
where
user0_.id=?
com.example.app.service.UserService : << -- In service
User ->
User [id=1, name=Jack]
Hibernate:
select
employee0_.user_id as user_id2_0_0_,
employee0_.id as id1_0_0_,
employee0_.id as id1_0_1_,
employee0_.user_id as user_id2_0_1_,
employee0_1_.salary as salary1_1_1_,
employee0_2_.hourly_wage as hourly_w1_2_1_,
case
when employee0_1_.id is not null then 1
when employee0_2_.id is not null then 2
when employee0_.id is not null then 0
end as clazz_1_
from
employee employee0_
left outer join
full_time employee0_1_
on employee0_.id=employee0_1_.id
left outer join
part_time employee0_2_
on employee0_.id=employee0_2_.id
where
employee0_.user_id=?
Now if its a Jackson Serialization problem I have visited Avoid Jackson serialization on non fetched lazy objects , Configure Jackson to omit lazy-loading attributes in Spring Boot , and many more, but all done by exdending WebMvcConfigurerAdapter which in spring5 i believe is deprecated ?
If its something to do with Spring Data JPA... then please shed some light because I always thought you need @Transaction annotation for lazy Fetch to associate relationship with hibernate session...
Sorry for the long thread...