Hibernate session closed with large volume - spring

I try to retrieve the data from a table linked to a parent table with the following entities:
Entity
#Table(name = "REF_BONJOUR_UNITE")
#NamedQuery(name = "UniteEntity.findAll", query = "SELECT u FROM UniteEntity u")
public class UniteEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "CODE_UNITE")
private String codeUnite;
// bi-directional many-to-one association to Insee
#OneToMany(mappedBy = "refBonjourUnite", fetch = FetchType.LAZY, cascade = CascadeType.MERGE )
private List<Insee> refBonjourInsees;
and the daughter entity :
#Entity
#Table(name = "REF_BONJOUR_INSEE")
#NamedQuery(name = "Insee.findAll", query = "SELECT i FROM Insee i")
public class Insee implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private InseePK id;
#Temporal(TemporalType.DATE)
#Column(name = "DATE_FIN_INSEE_GEO")
#IsOracleDate
private Date dateFinInseeGeo;
private String tylemt;
// bi-directional many-to-one association to UniteEntity
#ManyToOne
#JoinColumn(name = "CODE_UNITE_FK", insertable = false, updatable = false)
private UniteEntity refBonjourUnite;
When i try to access this list with a large amount of data, i get a failed to lazily initialize a collection of role, here exactly :
List<Insee> codeInsees = unite.getRefBonjourInsees();
Insee codeInsee = codeInsees.get(0)

Related

How do I map an #OneToMany and #ManyToOne relationship properly so that I can save and update the #OneToMany side with or without the #ManyToOne side

I have an app with Angular front end and Spring backend. The two classes in question here are (backend):
#Setter
#Getter
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table(name = "tournament_games")
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class TournamentGame {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "code", foreignKey = #ForeignKey(name = "code_fk"))
private TournamentCode code;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "type", foreignKey = #ForeignKey(name = "game_type_fk"))
private GameType type;
#Column(name = "home_score")
private int home_score;
#Column(name = "away_score")
private int away_score;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "result_type", foreignKey = #ForeignKey(name = "result_type_fk"))
private ResultType result_type;
#Column(name = "status")
private boolean status;
#Column(name = "round")
private int round;
#Column(name = "locked")
private boolean locked;
#OneToMany(mappedBy = "game", fetch = FetchType.EAGER)
private List<TournamentGamesPlayers> players = new ArrayList<>();
}
and
#Setter
#Getter
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table(name = "tournament_games_players")
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "game")
public class TournamentGamesPlayers implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#ManyToOne
#JoinColumn(name = "tournament_game_id")
private TournamentGame game;
#Id
#ManyToOne
#JoinColumn(name = "playerid")
private Player player;
#Column(name = "home")
private boolean home;
}
I need help figuring out how to persist the List<TournamentGamesPlayers> when I save and/or update a TournamentGame object. I generate 45 games. The first 30 games have known players, and so I set them before saving. The last 15 do not have entries for the TournamentGamesPlayers join table, because I need to add them later.
I am able to get some results with CascadeType.ALL on the #OneToMany side when I initially generate the games, but it fails when I try to update a game with a seemingly infinite recursion/stack overflow.
If I omit any cascade type, the games side get generated, but the join table #ManyToOne side does not get entered.
I ended up just putting the players back into the game table to make my life easier.
try putting CascadeType.MERGE, CascadeType.ALL "delete parent and orphans" (JPA CascadeType.ALL does not delete orphans).
Also, defining the relationship as EAGER and not ignoring the JSON property can have problems. I would add #JsonIgnore to one of the parts of the relationship

Fetching all entities with many to many relationships in repository layer : Hibernate with JPA

in my current project, I am using Hibernate with JPA.
I have entities as follows:
Entity A:
#Entity
#Table(name = "a")
public class A implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "uuid", strategy = "uuid2")
private String id;
#Column(name = "name")
private String name;
#OneToMany
private Set<Association> associations = new HashSet<>();
}
Entity B:
#Entity
#Table(name = "b")
public class B implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "uuid", strategy = "uuid2")
private String id;
#Column(name = "description")
private String description;
#OneToMany
private Set<Association> associations = new HashSet<>();
}
Entity Association:
#Entity
#Table(name = "association")
public class Association implements Serializable {
private static final long serialVersionUID = 1L;
#ManyToOne
#JoinColumn(name = "a_id", referencedColumnName = "id")
A a;
#ManyToOne
#JoinColumn(name = "b_id", referencedColumnName = "id")
B b;
...other columns..
}
Now I would like to implement repository layer for A as follows:
#Repository
public interface ARepository extends JpaRepository<A, Long> {
//Here I would like to write the function/query get all the As with many-to-many relationships.
}

QuerySyntaxException in Spring Data JPA custom query

I have a Entity:
#Entity
#Table(name = "story", schema = "")
#Data
public class Story implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "sID", unique = true, nullable = false)
private Long sID;
#Column(name = "vnName", nullable = false)
private String vnName;
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(pattern = "dd-MM-yyyy HH:mm:ss")
#Column(name = "sUpdate", length = 19)
private Date sUpdate;
}
And:
#Entity
#Table(name = "chapter", schema = "")
#Data
public class Chapter implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "chID", unique = true, nullable = false)
private Long chID;
#Column(name = "chName", nullable = false)
private String chName;
#JoinColumn(name = "sID", referencedColumnName = "sID")
#ManyToOne(fetch = FetchType.LAZY)
private Story story;
}
I had created custom pojo to get the latest update story with the latest chapter:
#Data
public class NewStory{
private Story story;
private Chapter chapter;
}
but when I get list :
#Repository
public interface StoryRepository extends CrudRepository<Story, Long> {
#Query(value="SELECT NEW com.apt.truyenmvc.entity.NewStory(s as newstory, c as newchapter)"
+ " FROM story s LEFT JOIN (SELECT * FROM Chapter c INNER JOIN "
+ " (SELECT MAX(c.chID) AS chapterID FROM Story s LEFT JOIN Chapter c ON s.sID = c.sID GROUP BY s.sID) d"
+ " ON c.chID = d.chapterID) c ON s.sID = c.sID order by s.sUpdate desc")
public List<NewStory> getTopView();
}
Error:
Warning error: org.hibernate.hql.internal.ast.QuerySyntaxException: story is not mapped.
Who could help me fix it? Or could it be done in a different way?
The error is pretty self explainatory. And its just a typo in your query. You are using story. And obviously thats not mapped as an Entity.
Fix it to Story

Spring JPA: How to insert data to join many tables with #ManytoMany relationship

I'm starting to learn Spring Java Framework . I created some Enity to join 2 Model like my Database. And now I want to insert to Join Table by JpaRepository. What i have to do?
This is my Code (Please fix help me me if something is not right)
Model Users_RoomId to define Composite Primary Key
#Embeddable
public class Users_RoomId implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "ID_room", nullable = false)
private String idRoom;
#Column(name = "user_id", nullable = false)
private int idUser;
}
Model Users_Room to join 2 Model Users and Room
#Entity
#Table(name ="bookroom")
public class Users_Room {
#EmbeddedId
private Users_RoomId usersroomId;
#ManyToOne
#MapsId("idRoom")
private Room room;
#ManyToOne
#MapsId("idUser")
private Users users;
#Column(name = "Bookday")
private String bookday;
Model Users and Room I used annotation #OneToMany
Model Users
#Entity
#Table(name = "users")
public class Users implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id", nullable = false)
private int id;
#Column(name = "name", nullable = false)
private String name;
#Column(name = "email")
private String email;
#Column(name = "pass")
private String pass;
#Column(name = "role")
private int role;
#OneToMany(mappedBy = "users")
private List<Users_Room> user;
Model Room
#Entity
#Table(name ="room")
public class Room implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID_room", nullable = false)
private String id;
#Column(name = "name_room", nullable = false)
private String name;
#Column(name = "Description")
private String describe;
#ManyToOne
#JoinColumn(name = "ID_status")
private Status status;
#Column(name = "room_image")
private String image;
public Room() {
super();
}
#ManyToOne
#JoinColumn(name = "ID_kind")
private KindRoom kind;
#OneToMany(mappedBy = "room")
private List<Users_Room> rooms;
This is my database
So I don't know how to insert a new bookroom with iduser,idroom and bookday with JPA repository.. It'necessary to write Query in JPARepository or We just need to use method save() to insert data
Thanks everyone
I had same problem and solved with following code. I used method save() to insert data. Following code is 'createRoom' method in 'RoomService.java'.
RoomService.java
private final RoomRepository roomRepository;
private final UserRoomRepository userRoomRepository;
private final UserRepository userRepository;
public RoomService(RoomRepository roomRepository, UserRoomRepository userRoomRepository, UserRepository userRepository) {
this.roomRepository = roomRepository;
this.userRoomRepository = userRoomRepository;
this.userRepository = userRepository;
}
#Transactional
public RoomDto createRoom(Long userId, Long chattingUserId) {
Room room = roomRepository.save(new Room());
room.addUserRoom(userRepository.findById(userId).orElseThrow(()->new NoSuchElementException("No User")));
room.addUserRoom(userRepository.findById(chattingUserId).orElseThrow(()->new NoSuchElementException("No User")));
userRoomRepository.save(new UserRoom(userRepository.findById(userId).orElseThrow(()->new NoSuchElementException("No User")),room));
userRoomRepository.save(new UserRoom(userRepository.findById(chattingUserId).orElseThrow(()->new NoSuchElementException("No User")),room));
RoomDto roomDto = RoomDto.of(room);
return roomDto;
}

Hibernate 4 Entity Mapping with Spring

I've got 2 entity classes as follows:
#Entity
#Table(name = "USER_ACCT")
public class UserAccount implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="USER_ACCT_ID_SEQ")
#SequenceGenerator(name="USER_ACCT_ID_SEQ", sequenceName="USER_ACCT_ID_SEQ")
#Column(name = "USER_ACCT_ID")
protected Long id;
#Basic(optional = false)
#Column(length = 50, unique = true)
private String username;
#Basic(optional = false)
#Column(length = 128, nullable = false)
private String password;
#ManyToMany(targetEntity = UserPermission.class)
#JoinTable(name = "USER_ACCT_PERM",
joinColumns = #JoinColumn(name = "USER_ACCT_ID"),
inverseJoinColumns = #JoinColumn(name = "USER_PERM_ID", referencedColumnName = "USER_PERM_ID"))
private Set<UserPermission> permissions;
// getters and setters...
}
AND
#Entity
#Table(name = "USER_PERM")
public class UserPermission implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="USER_PERM_ID_SEQ")
#SequenceGenerator(name="USER_PERM_ID_SEQ", sequenceName="USER_PERM_ID_SEQ")
#Column(name = "USER_PERM_ID")
protected Long id;
#Column(name = "PERM", unique = true, length = 255, nullable = false)
private String authority;
// getters and setters...
}
Now when I create an object of UserAccount and try to save it using the session factory it gives me the following error:
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.rpm.domain.UserPermission
Shouldn't the UserPermission class be saved by itself??
This is the code that is used to persist:
#Transactional
public void addUser(){
Set<UserPermission> permissions = new HashSet<UserPermission>();
permissions.add(new UserPermission("ROLE_ADMIN"););
sessionFactory.getCurrentSession().save(new UserAccount("admin", "d033e22ae348aeb5660fc2140aec35850c4da997", permissions));
}
Not unless you specify the cascade options.

Resources