I am working through my first Spring boot application using Hibernate/JPA. I have created two @Entities
with a @ManyToMany
mapping: Team
and Game
.
Currently, the database has a table holding teams
and I'd like to insert a game
which references two teams
.
The issue is that i am getting the error:
`org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataLoader': Invocation of init method failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.data.entities.FootballTeam.homeGames, could not initialize proxy - no Session
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:408) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:838) ~[spring-context-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537) ~[spring-context-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.0.RELEASE.jar:1.3.0.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) [spring-boot-1.3.0.RELEASE.jar:1.3.0.RELEASE]
at org.springframework.boot.SpringApplication.doRun(SpringApplication.java:347) [spring-boot-1.3.0.RELEASE.jar:1.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:295) [spring-boot-1.3.0.RELEASE.jar:1.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1112) [spring-boot-1.3.0.RELEASE.jar:1.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1101) [spring-boot-1.3.0.RELEASE.jar:1.3.0.RELEASE]
at com.example.FootballPoolSpringSpringBoot.main(FootballPoolSpringSpringBoot.java:11) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_65]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_65]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_65]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_65]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.3.0.RELEASE.jar:1.3.0.RELEASE]
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.data.entities.FootballTeam.homeGames, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:576) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:215) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:555) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.write(AbstractPersistentCollection.java:400) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.collection.internal.PersistentBag.add(PersistentBag.java:314) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at com.example.service.DataLoader.loadData(DataLoader.java:106) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_65]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_65]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_65]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_65]
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:354) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:305) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:133) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
... 23 common frames omitted`.
What am I doing wrong?
@Entity
public class FootballTeam {
private FootballTeam(){/**/}
public FootballTeam(String teamName) {
this.teamName = teamName;
}
@Id
@GeneratedValue
private Long teamId;
@Column(name = "team_name", unique = true)
private String teamName;
@Column(name = "short_name", unique = true)
private String teamShortName;
private String teamLeague;
private String teamDivision;
@Embedded
private Location teamLocation;
@ManyToMany(cascade = CascadeType.ALL, mappedBy = "favoriteTeams")
private List<Users> fans = new ArrayList<>();
@OneToMany(mappedBy = "homeTeam")
List<FootballGame> homeGames = new ArrayList<>();
@OneToMany(mappedBy = "visitingTeam")
List<FootballGame> awayGames = new ArrayList<>();
/* getters and setters omitted for brevity */
}
Game.java
@Entity
@Table(name = "football_game",
uniqueConstraints= @UniqueConstraint(
columnNames={"played_on", "home_team", "visiting_team"}))
public class FootballGame {
private FootballGame(){/**/}
public FootballGame(Date playedOn, FootballTeam homeTeam, FootballTeam visitingTeam) {
this.homeTeam = homeTeam;
this.playedOn = playedOn;
this.visitingTeam = visitingTeam;
}
@Id
@GeneratedValue
private Long gameId;
@Column(name = "played_on", nullable = false)
private Date playedOn;
@ManyToOne(cascade = CascadeType.MERGE)
@JoinColumn(name = "home_team", nullable = false)
private FootballTeam homeTeam;
@ManyToOne(cascade = CascadeType.MERGE)
@JoinColumn(name = "visiting_team", nullable = false)
private FootballTeam visitingTeam;
private int homeTeamScore;
private int visitingTeamScore;
@OneToOne(mappedBy = "footballGame")
private FootballPool footballPool;
/* getters and setters omitted for brevity */
}
DataLoader.class
@Service
public class DataLoader {
private FootballTeamRepository teamRepository;
private FootballGameRepository gameRepository;
@Autowired
public DataLoader(FootballGameRepository gameRepository,
FootballTeamRepository teamRepository) {
this.gameRepository = gameRepository;
this.teamRepository = teamRepository;
}
@PostConstruct
private void loadData(){
FootballTeam f4 = new FootballTeam("lil Shin-Kickers");
f4.setTeamLocation(new Location("California"));
teamRepository.save(f4);
FootballTeam f1 = new FootballTeam("Tumble Tots");
f1.setTeamLocation(new Location("Colorado"));
teamRepository.save(f1);
FootballTeam homeTeam = teamRepository.findTeamByTeamNameIgnoreCase("lil Shin-Kickers");
System.out.println(homeTeam.getTeamName());
FootballTeam visitingTeam = teamRepository.findTeamByTeamNameIgnoreCase("Tumble Tots");
FootballGame footballGame = new FootballGame(new Date(), homeTeam, visitingTeam);
footballGame.setHomeTeamScore(7);
footballGame.setVisitingTeamScore(21);
gameRepository.save(footballGame);
}