Hello my professionals I have a simple question here that I would like to beg to solve this..
this is an Entity of Member
@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
/*@ToString(of = {"id", "username", "age"})*/
public class Member {
@Id
/*@GeneratedValue(strategy = GenerationType.IDENTITY)*/
@Column(name = "member_id")
private Long id;
private String username;
private int age;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "member")
private List<Team> teams;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "member")
private List<Coach> coachs;
}
And this is an Entity of Coach
@Entity
@AllArgsConstructor
@Getter
@Builder
@Setter
@NoArgsConstructor
@ToString(of = {"id","name","career"})
public class Coach {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name= "coach_id")
private Long id;
@Column
private String name;
@Column
private String career;
@ManyToOne(fetch = FetchType.LAZY,cascade = ALL)
@JoinColumn(name = "member_id")
private Member member;
@OneToOne(fetch = FetchType.LAZY,cascade = ALL)
@JoinColumn(name = "team_id")
private Team team;
}
and This is Controller Code
@GetMapping("/member")
public void createUser(){
Member m = memberService.createMember();
Coach c = m.getCoachs().get(0);
log.info(c.getName());
}
and This is Service Code
private final MemberRepository memberRepository;
@Transactional
public Member createMember(){
return memberRepository.findMemberById(3L);
}
and the last this is RepositoryCode
Member findMemberById(Long id);
So my question is that when i printed out Coach's name at the controller on console
it printed out so well.
but what I know the Transaction is over from the service So the persistence container is closed that means coach name can't be imported cause it's LAZY loading and persistence container is closed but it was printed out well
I want to know the reason why ...
here are the console results Thanks !!
[2022-01-10 23:27:46.835] [http-nio-9000-exec-2] [] INFO o.a.c.c.C.[.[.[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
[2022-01-10 23:27:46.835] [http-nio-9000-exec-2] [] INFO o.s.w.s.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
[2022-01-10 23:27:46.855] [http-nio-9000-exec-2] [] INFO o.s.w.s.DispatcherServlet - Completed initialization in 19 ms
Hibernate:
/* select
generatedAlias0
from
Member as generatedAlias0
where
generatedAlias0.id=:param0 */ select
member0_.member_id as member_i1_1_,
member0_.age as age2_1_,
member0_.username as username3_1_
from
member member0_
where
member0_.member_id=?
[2022-01-10 23:27:47.007] [http-nio-9000-exec-2] [4c0222d3] INFO p6spy - #1641824867007 | took 15ms | statement | connection 1| url jdbc:mariadb://patrick-lab.cjeq2ffynlc2.ap-northeast-2.rds.amazonaws.com:3306/patricklab?characterEncoding=UTF-8&serverTimezone=UTC
/* select generatedAlias0 from Member as generatedAlias0 where generatedAlias0.id=:param0 */ select member0_.member_id as member_i1_1_, member0_.age as age2_1_, member0_.username as username3_1_ from member member0_ where member0_.member_id=?
/* select generatedAlias0 from Member as generatedAlias0 where generatedAlias0.id=:param0 */ select member0_.member_id as member_i1_1_, member0_.age as age2_1_, member0_.username as username3_1_ from member member0_ where member0_.member_id=3;
[2022-01-10 23:27:47.170] [http-nio-9000-exec-2] [4c0222d3] INFO p6spy - #1641824867170 | took 12ms | commit | connection 1| url jdbc:mariadb://patrick-lab.cjeq2ffynlc2.ap-northeast-2.rds.amazonaws.com:3306/patricklab?characterEncoding=UTF-8&serverTimezone=UTC
;
Hibernate:
select
coachs0_.member_id as member_i4_0_0_,
coachs0_.coach_id as coach_id1_0_0_,
coachs0_.coach_id as coach_id1_0_1_,
coachs0_.career as career2_0_1_,
coachs0_.member_id as member_i4_0_1_,
coachs0_.name as name3_0_1_,
coachs0_.team_id as team_id5_0_1_
from
coach coachs0_
where
coachs0_.member_id=?
[2022-01-10 23:27:47.200] [http-nio-9000-exec-2] [4c0222d3] INFO p6spy - #1641824867200 | took 12ms | statement | connection 1| url jdbc:mariadb://patrick-lab.cjeq2ffynlc2.ap-northeast-2.rds.amazonaws.com:3306/patricklab?characterEncoding=UTF-8&serverTimezone=UTC
select coachs0_.member_id as member_i4_0_0_, coachs0_.coach_id as coach_id1_0_0_, coachs0_.coach_id as coach_id1_0_1_, coachs0_.career as career2_0_1_, coachs0_.member_id as member_i4_0_1_, coachs0_.name as name3_0_1_, coachs0_.team_id as team_id5_0_1_ from coach coachs0_ where coachs0_.member_id=?
select coachs0_.member_id as member_i4_0_0_, coachs0_.coach_id as coach_id1_0_0_, coachs0_.coach_id as coach_id1_0_1_, coachs0_.career as career2_0_1_, coachs0_.member_id as member_i4_0_1_, coachs0_.name as name3_0_1_, coachs0_.team_id as team_id5_0_1_ from coach coachs0_ where coachs0_.member_id=3;
[2022-01-10 23:27:47.213] [http-nio-9000-exec-2] [4c0222d3] INFO m.p.l.m.c.MemberController - Coach1
I believe it is because you are using the spring-boot default setting which the spring.jpa.open-in-view
is set to true .
This property enables OpenSessionInView
pattern which you can simply think that a transaction will be opened automatically for you at the very first beginning when processing any HTTP request (e.g. in the Servlet Filter etc). Because of this , a transaction is actually already open before your service method executes and it is still active after your service method completes. Hence you will not experience any LazyInitializationException
even after you access non-initialized properties outside the service method as the transaction is still active.
There is a strong debate about whether or not spring-boot should enable it by default in the past . You can refer this for more details if you are interested. I personally would recommend to turn it off.