So first a bit of back story. The issue I am having is when I create a user. Previously I had tried to create a user and assign them a role separately before discovering that by inserting into the SEC_USER_ROLE table the program was also inserting into the APP_USER table and I was getting an error about inserting duplicate values into the parent table. However, now by creating the user and role together I am getting the following error:
Primary key should be primitive (or list of primitives for composite
pk) , an instance of java.lang.Long with the primary keys filled in or
an instance of WebIntSecRole.......
Code as follows, not sure where I'm goin g wrong or the best solution at this point.
Admin.java:
//New User Creation
WebIntUser newUser = new WebIntUser();
newUser.setLoginId(newLoginName);
newUser.setCreatedBy(loggedUser);
newUser.setCreatedOn(today);
newUser.setDbAuth(true);
newUser.setDeleted(false);
newUser.setDisabled(false);
newUser.setEmail(newEmail);
newUser.setEncrypted(true);
newUser.setEncryptPassword(true);
newUser.setFirstName(newFirstName);
newUser.setLastName(newLastName);
newUser.setUpdatedBy(loggedUser);
newUser.setUpdatedOn(today);
newUser.setVersion(1);
newUser.setLdapId(1);
//userService.createUser(newUser);
//Set role for new user
WebIntSecRoleUser newUserRole = new WebIntSecRoleUser();
newUserRole.setUser(newUser);
newUserRole.setDeleted(false);
newUserRole.setRole(userService.selectRoleById(1));
//newUserRole.setCreatedBy(loggedUser);
//newUserRole.setCreatedOn(today);
//newUserRole.setUpdatedBy(loggedUser);
//newUserRole.setUpdatedOn(today);
newUserRole.setVersionNumber(0);
userService.createRole(newUserRole);
WebIntUser.java
#Entity
#Table(name = "APP_USER")
#EntityListeners(value = { AuditChangeListener.class })
public class WebIntUser implements Serializable {
public WebIntUser() {
};
public WebIntUser(String login, String pass) {
this.loginId = login;
this.password = pass;
}
private Integer userId;
private String loginId;
private String password;
private String firstName;
private String lastName;
private String email;
private boolean disabled;
private boolean deleted;
private boolean dbAuth;
private boolean isEncrypted;
private boolean encryptPassword;
private Date lastLogin;
private Date prevLogin;
private Integer version;
private Date lastPasswordChange;
private Date createdOn;
private Date updatedOn;
private String createdBy;
private String updatedBy;
private Integer ldapId;
public static interface propertyName {
String userId = "userId";
String loginId = "loginId";
String password = "password";
String firstName = "firstName";
String lastName = "lastName";
String email = "email";
String disabled = "disabled";
String deleted = "deleted";
String dbAuth = "dbAuth";
String isEncrypted = "isEncrypted";
String encryptPassword = "encryptPassword";
String lastLogin = "lastLogin";
String prevLogin = "prevLogin";
String version = "version";
String lastPasswordChange = "lastPasswordChange";
String createdOn = "createdOn";
String updatedOn = "updatedOn";
String createdBy = "createdBy";
String updatedBy = "updatedBy";
String ldapId = "ldapId";
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "USER_ID", nullable = false)
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
.....getters/setters
}
WebIntSecRoleUser.java:
#Entity
#Table(name = "SEC_ROLE_USER")
#EntityListeners(value = {AuditInfoChangeListener.class})
public class WebIntSecRoleUser implements AuditableDomainObject {
private Long id;
private WebIntSecRole role;
private WebIntUser user;
private boolean deleted;
private AuditInfo auditInfo;
private long versionNumber;
private Date createdOn;
private Date updatedOn;
private String createdBy;
private String updatedBy;
public interface propertyName extends Auditable.propertyName {
String id="id";
String role="role";
String user="user";
String deleted = "deleted";
String createdOn = "createdOn";
String updatedOn = "updatedOn";
String createdBy = "createdBy";
String updatedBy = "updatedBy";
}
public static interface permissionKey{
String UPDATE="SecRoleUser.U";
}
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "ROLE_USER_ID",nullable = false, unique = true)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#JoinColumn(name="ROLE_ID", nullable=false)
public WebIntSecRole getRole() {
return role;
}
public void setRole(WebIntSecRole role) {
this.role = role;
}
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name="USER_ID", nullable = false)
public WebIntUser getUser() {
return user;
}
public void setUser(WebIntUser user) {
this.user = user;
}
Getters/setters
}
Note: There is some commented out code that I'm either trying not to use anymore, or in the case of Created By and Created On etc I was getting errors for multiple inserts.
In my opinion you have missed the #ManyToOne mapping on the WebIntSecRole. You only specified the #JoinColumn.
#ManyToOne(/* desired options */)
#JoinColumn(name="ROLE_ID", nullable=false)
public WebIntSecRole getRole() {
return role;
Related
I am not able to fetch all records from two tables using the below query
I have tried this but I am getting a result from one table only. I want a result of both the tables i.e, client_software_param_mapping and client_file_configuration having the same ClientId which is a foreign key from third pojo(client_software_configuration) to first and second pojo.
public Result showClientConfiguration() {EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("defaultPU");
EntityManager entityManager = entityManagerFactory.createEntityManager();
Query q=entityManager.
createQuery("SELECT c FROM client_software_param_mapping c JOIN fetch client_file_configuration f ON c.ClientId=f.ClientId");
List data =q.getResultList();
return ok(Json.toJson(data));
}
first pojo
#Entity
public class client_file_configuration {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String sourceFolder;
private String sourceFile;
private String processingFolder;
private String processingFile;
private String processedFolder;
private int intervalInMin;
private String readAfterDelay;
private String parserClass;
private String directoryMode;
private String fileMode;
private String actionMode;
private String type;
private String fileExpressionResolver;
#OneToOne
#JoinColumn(name = "ClientId")
private client_software_configuration clientSoftwareConfiguration;
public client_software_configuration getClientSoftwareConfiguration() {
return clientSoftwareConfiguration;
}
public void setClientSoftwareConfiguration(client_software_configuration clientSoftwareConfiguration) {
this.clientSoftwareConfiguration = clientSoftwareConfiguration;
}
}
secondpojo
#Entity
public class client_software_param_mapping {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String paramKey;
private String paramValue;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getParamKey() {
return paramKey;
}
public void setParamKey(String paramKey) {
this.paramKey = paramKey;
}
public String getParamValue() {
return paramValue;
}
public void setParamValue(String paramValue) {
this.paramValue = paramValue;
}
#ManyToOne
#JoinColumn(name = "ClientId")
private client_software_configuration clientSoftwareConfiguration;
public client_software_configuration getClientSoftwareConfiguration() {
return clientSoftwareConfiguration;
}
public void setClientSoftwareConfiguration(client_software_configuration clientSoftwareConfiguration) {
this.clientSoftwareConfiguration = clientSoftwareConfiguration;
}
}
thirdpojo
#Entity
public class client_software_configuration {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String url;
private int port;
private String endPoint;
private String isPost;
private String isPing;
private String params;
private int serialNo;
private String dateFormat;
private String token;
}
this is the right query as it is returning the object of the third pojo present at that ClientId so it is able to understand the type of ClientId.JPQL never uses table and column names. It always uses entity names and their mapped fields/properties names.so here I have taken the object of the third pojo having the ClientId field.
select c,p from client_file_configuration c,client_software_param_mapping p where c.clientSoftwareConfiguration = p.clientSoftwareConfiguration
I am trying to save a list of directors of a company whenever i create a new merchant, thus i have a #ManyToOne relationship between Director and Merchant respectively.
Thus far i have managed to get it to save the list of directors and the merchant when i do a POST. However when i do a GET request i do not get back the directors, the list comes back empty. When i check in the database, the joining column is empty as shown in the image but the rest of the data is present. How can i solve this issue?
This is my code :
Director.java
#Entity
#Table(name = "Directors")
public class Director {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long directorID;
#Cascade({org.hibernate.annotations.CascadeType.ALL})
#ManyToOne
#JoinColumn(name = "merchantNumber")
private Merchant merchant;
#NotBlank
private String name;
#NotBlank
private String surname;
public Director() {
}
public Director(long directorID, Merchant merchant, String name, String surname) {
this.directorID = directorID;
this.merchant = merchant;
this.name = name;
this.surname = surname;
}
...
Getters and setters
DirectorRepository.java
public interface DirectorRepository extends CrudRepository<Director, String> {
}
Merchant.java
public class Merchant {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int merchantNumber;
#NotBlank
private String merchantID;
#NotBlank
private String businessName;
#Cascade({org.hibernate.annotations.CascadeType.ALL})
#OneToMany(mappedBy = "merchant")
private List<Director> directors;
#NotBlank
private String userName;
public Merchant(int merchantNumber, String merchantID, String businessName, List<Director> directors, String userName ) {
this.merchantNumber = merchantNumber;
this.merchantID = merchantID;
this.businessName = businessName;
this.directors = directors;
this.userName = userName;
}
...
Getter and setters
MerchantService.java
public ResponseMerchantQuery createMerchant(Merchant merchant) {
if( merchant == null || merchant.getMerchantID()== null){
throw new ResourceNotFoundException("Empty", "Missing Data Exception");
} else {
merchant.setPassword(passwordEncoder.encode(merchant.getPassword()));
merchantRepository.save(merchant);
String merchantNum = Long.toString(merchant.getMerchantNumber());
return new ResponseMerchantQuery(merchantNum, "Merchant Created Successfully");
}
}
MerchantController.java
#RequestMapping(method = RequestMethod.POST, value = "/api/merchants")
public ResponseMerchantQuery createMerchant(#Valid #RequestBody Merchant merchant){
System.out.println("size of merchnat " + merchant.getDirectors().size());
return merchantService.createMerchant(merchant);
}
I have two tables in a relationship with each other.
When I delete a line of data in the parent table.
If the data stream that is used in the table, the error message.
If not, to delete data
SQL Server Foreign Key Update and Delete Rules
No Action : Not allowed. Error message would be generated. (I want to use this exception)
Delete row in Ma_DM_NGAN_HANG throw Exception
#Entity
#Table(name = "Ma_DM_NGAN_HANG", schema = "dbo", uniqueConstraints = #UniqueConstraint(columnNames = "MANH"))
public class DmNganHang implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
// Fields
private Long id;
private String manh;
private String tennh;
private String tentat;
private String diachi;
private String dienthoai;
private String fax;
private String email;
private String taikhoan;
private String masothue;
private Integer idDonvi;
private String website;
private String filter;
private List<DmNhanVien> dmNhanViens = new ArrayList<DmNhanVien>();
private List<DmDoiTacTknganhang> dmDoiTacTknganhangs = new ArrayList<DmDoiTacTknganhang>();
// Constructors
/** default constructor */
public DmNganHang() {
}
/** minimal constructor */
public DmNganHang(Long id, String manh, String tennh, String taikhoan) {
this.id = id;
this.manh = manh;
this.tennh = tennh;
this.taikhoan = taikhoan;
}
/** full constructor */
public DmNganHang(Long id, String manh, String tennh, String tentat,
String diachi, String dienthoai, String fax, String email,
String taikhoan, String masothue, Integer idDonvi, String website,
String filter, List<DmNhanVien> dmNhanViens,
List<DmDoiTacTknganhang> dmDoiTacTknganhangs) {
this.id = id;
this.manh = manh;
this.tennh = tennh;
this.tentat = tentat;
this.diachi = diachi;
this.dienthoai = dienthoai;
this.fax = fax;
this.email = email;
this.taikhoan = taikhoan;
this.masothue = masothue;
this.idDonvi = idDonvi;
this.website = website;
this.filter = filter;
this.dmNhanViens = dmNhanViens;
this.dmDoiTacTknganhangs = dmDoiTacTknganhangs;
}
// Property accessors
#Id
#Column(name = "ID", unique = true, nullable = false, precision = 18, scale = 0)
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
// Code ......
#JsonInclude(JsonInclude.Include.NON_EMPTY)
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "dmNganHang")
public List<DmNhanVien> getDmNhanViens() {
return this.dmNhanViens;
}
public void setDmNhanViens(List<DmNhanVien> dmNhanViens) {
this.dmNhanViens = dmNhanViens;
}
#JsonInclude(JsonInclude.Include.NON_EMPTY)
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "dmNganHang")
public List<DmDoiTacTknganhang> getDmDoiTacTknganhangs() {
return this.dmDoiTacTknganhangs;
}
public void setDmDoiTacTknganhangs(
List<DmDoiTacTknganhang> dmDoiTacTknganhangs) {
this.dmDoiTacTknganhangs = dmDoiTacTknganhangs;
}
}
#Entity
#Table(name = "Ma_DM_NHAN_VIEN", schema = "dbo", uniqueConstraints = #UniqueConstraint(columnNames = {
"MANV", "IdDonvi" }))
public class DmNhanVien implements java.io.Serializable {
// Fields
/**
*
*/
private static final long serialVersionUID = 1L;
private Long id;
private DmNganHang dmNganHang;
private DmPhongBan dmPhongBan;
private String manv;
private String tennv;
private String diachi;
private String hkthuongtru;
private String dienthoai;
private String masothue;
private String socmt;
private Date ngaycap;
private String noicap;
private Boolean canhancutru;
private String nhom;
private String taikhoannh;
private String tinhtranghonnhan;
private Boolean gioitinh;
private Date ngaysinh;
private Integer idDonvi;
private String filter;
private List<TnChungtuthunhap> tnChungtuthunhaps = new ArrayList<TnChungtuthunhap>();
private List<TnNguoiphuthuoc> tnNguoiphuthuocs = new ArrayList<TnNguoiphuthuoc>();
private List<DmHopDong> dmHopDongs = new ArrayList<DmHopDong>();
// Constructors
/** default constructor */
public DmNhanVien() {
}
/** minimal constructor */
public DmNhanVien(Long id, DmNganHang dmNganHang, DmPhongBan dmPhongBan,
String manv, String tennv, String diachi, String taikhoannh) {
this.id = id;
this.dmNganHang = dmNganHang;
this.dmPhongBan = dmPhongBan;
this.manv = manv;
this.tennv = tennv;
this.diachi = diachi;
this.taikhoannh = taikhoannh;
}
/** full constructor */
public DmNhanVien(Long id, DmNganHang dmNganHang, DmPhongBan dmPhongBan,
String manv, String tennv, String diachi, String hkthuongtru,
String dienthoai, String masothue, String socmt, Date ngaycap,
String noicap, Boolean canhancutru, String nhom, String taikhoannh,
String tinhtranghonnhan, Boolean gioitinh, Date ngaysinh,
Integer idDonvi, String filter,
List<TnChungtuthunhap> tnChungtuthunhaps,
List<TnNguoiphuthuoc> tnNguoiphuthuocs, List<DmHopDong> dmHopDongs) {
this.id = id;
this.dmNganHang = dmNganHang;
this.dmPhongBan = dmPhongBan;
this.manv = manv;
this.tennv = tennv;
this.diachi = diachi;
this.hkthuongtru = hkthuongtru;
this.dienthoai = dienthoai;
this.masothue = masothue;
this.socmt = socmt;
this.ngaycap = ngaycap;
this.noicap = noicap;
this.canhancutru = canhancutru;
this.nhom = nhom;
this.taikhoannh = taikhoannh;
this.tinhtranghonnhan = tinhtranghonnhan;
this.gioitinh = gioitinh;
this.ngaysinh = ngaysinh;
this.idDonvi = idDonvi;
this.filter = filter;
this.tnChungtuthunhaps = tnChungtuthunhaps;
this.tnNguoiphuthuocs = tnNguoiphuthuocs;
this.dmHopDongs = dmHopDongs;
}
// Property accessors
#Id
#Column(name = "ID", unique = true, nullable = false, precision = 18, scale = 0)
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
#JsonIgnore
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "ID_NGANHANG", nullable = false)
public DmNganHang getDmNganHang() {
return this.dmNganHang;
}
public void setDmNganHang(DmNganHang dmNganHang) {
this.dmNganHang = dmNganHang;
}
#JsonIgnore
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "ID_PHONGBAN", nullable = false)
public DmPhongBan getDmPhongBan() {
return this.dmPhongBan;
}
// Code .....
}
Method Delete
public <T, E extends Serializable> void delete(T entity) {
entity = entityManager.merge(entity);
entityManager.remove(entity);
}
public <T, E extends Serializable> void deletefindOne(T entity) {
E id = (E) CommonUtil.invoke(entity, "getId");
JpaRepository repository = new SimpleJpaRepository(entity.getClass(),
entityManager);
repository.delete(repository.findOne(id));
}
Thanks
I have this part of database schema:
and this User entity:
#Entity
#Table(name = "user", catalog = "ats")
public class User implements java.io.Serializable{
private static final long serialVersionUID = 1L;
private String username;
private boolean enabled;
private Role role;
private ClientVersion clientVersion;
private ClientLicense clientLicense;
#JsonIgnore
private Set<NotificationHasUser> notificationHasUsers = new HashSet<NotificationHasUser>(0);
public User() {
}
public User(String username, boolean enabled) {
this.username = username;
this.enabled = enabled;
}
public User(String username, boolean enabled, Role role, Set<NotificationHasUser> notificationHasUsers) {
this.username = username;
this.enabled = enabled;
this.role = role;
this.notificationHasUsers = notificationHasUsers;
}
#Id
#Column(name = "username", unique = true, nullable = false, length = 45)
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
#Column(name = "enabled", nullable = false)
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_role", nullable = false)
public Role getRole() {
return this.role;
}
public void setRole(Role role) {
this.role = role;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_clientVersion", nullable = false)
public ClientVersion getClientVersion() {
return this.clientVersion;
}
public void setClientVersion(ClientVersion clientVersion) {
this.clientVersion = clientVersion;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.user")
public Set<NotificationHasUser> getNotificationHasUser() {
return this.notificationHasUsers;
}
public void setNotificationHasUser(Set<NotificationHasUser> notificationHasUsers) {
this.notificationHasUsers = notificationHasUsers;
}
#OneToOne(fetch = FetchType.LAZY, mappedBy = "user")
public ClientLicense getClientLicense(){
return this.clientLicense;
}
public void setClientLicense(ClientLicense clientLicense){
this.clientLicense = clientLicense;
}
}
All works fine until I add a new clientlicense. If I add this I receive an infinite loop:
Could not write content: Infinite recursion (StackOverflowError) (through reference chain: com.domain.User["clientLicense"]->com.domain.ClientLicense["user"]->com.domain.User["clientLicense"]->com.domain.ClientLicense["user"]->com.domain.User["clientLicense"]->com.domain.ClientLicense["user"]->com.domain.User["clientLicense"]->com.domain.ClientLicense["user"]->com.domain.User["clientLicense"]-....
This is my ClientLicense entity
#Entity
#Table(name = "clientlicense", catalog = "ats")
public class ClientLicense implements java.io.Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer idClientLicense;
private Date startDate;
private Date endDate;
private int counter;
private String macAddress;
private String cpuId;
private User user;
public ClientLicense() {
}
/**
* #param startDate
* #param endDate
* #param counter
* #param macAddress
* #param cpuId
* #param users
*/
public ClientLicense(Date startDate, Date endDate, int counter, String macAddress, String cpuId, User user) {
super();
this.startDate = startDate;
this.endDate = endDate;
this.counter = counter;
this.setMacAddress(macAddress);
this.setCpuId(cpuId);
this.user = user;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id_clientLicense", unique = true, nullable = false)
public Integer getIdClientLicense() {
return this.idClientLicense;
}
public void setIdClientLicense(Integer idClientLicense) {
this.idClientLicense = idClientLicense;
}
#Column(name = "startDate", nullable = false)
public Date getStartDate() {
return this.startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
#Column(name = "endDate", nullable = false)
public Date getEndDate() {
return this.endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
#Column(name = "counter", nullable = false)
public int getCounter() {
return this.counter;
}
public void setCounter(int counter) {
this.counter = counter;
}
/**
* #return the macAddress
*/
#Column(name = "macAddress", nullable = false)
public String getMacAddress() {
return macAddress;
}
/**
* #param macAddress the macAddress to set
*/
public void setMacAddress(String macAddress) {
this.macAddress = macAddress;
}
/**
* #return the cpuId
*/
#Column(name = "cpuId", nullable = false)
public String getCpuId() {
return cpuId;
}
/**
* #param cpuId the cpuId to set
*/
public void setCpuId(String cpuId) {
this.cpuId = cpuId;
}
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "id_username")
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
}
This is my first OneToOne relationship, what is the correct annotation that I have to use? I read some example but I don't understand fine, they are different each other.
try something like this.
public class User {
private ClientLicense clientLicense;
#OneToOne(fetch = FetchType.LAZY, mappedBy = "user")
public ClientLicense getClientLicense() {
return this.clientLicense;
}
}
public class ClientLicense {
private User user;
#OneToOne
#JoinColumn(name = "id_username")
public User getUser() {
return this.user;
}
}
The problem is that the two entities have no way of finding out that the two fields are actually specifying a single relationship. So hibernate assumes that they are not the same relationship and therefore tries to fetch them (because one-to-one relationships are fetched eagerly by default).
Add #OneToOne(mappedBy = "user") before the clientLicense field in the User class to tell hibernate that this field is "mapped by" the same column as the user field in the ClientLicense class
I have the following 2 entities:
#Entity
public class User implements java.io.Serializable {
private Integer iduser;
private String email;
private String password;
private Byte enabled;
private Set<Token> tokens = new HashSet<>(0);
public User() {
}
public User(String email, String password, Byte enabled/*, Set groupRights*/, Set tokens) {
this.email = email;
this.password = password;
this.enabled = enabled;
this.tokens = tokens;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "iduser", unique = true, nullable = false)
public Integer getIduser() {
return this.iduser;
}
public void setIduser(Integer iduser) {
this.iduser = iduser;
}
#Column(name = "email", unique = true, length = 45)
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name = "password", length = 60)
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
#Column(name = "enabled")
public Byte getEnabled() {
return this.enabled;
}
public void setEnabled(Byte enabled) {
this.enabled = enabled;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
public Set<Token> getTokens() {
return this.tokens;
}
public void setTokens(Set<Token> tokens) {
this.tokens = tokens;
}
}
#Entity
public class Token implements java.io.Serializable {
private String idtoken;
private User user;
private Date tokenTtl;
private String ipLock;
public Token() {
}
public Token(String idtoken) {
this.idtoken = idtoken;
}
public Token(String idtoken, User user, Date tokenTtl, String ipLock) {
this.idtoken = idtoken;
this.user = user;
this.tokenTtl = tokenTtl;
this.ipLock = ipLock;
}
#Id
#Column(name = "idtoken", unique = true, nullable = false, length = 36)
public String getIdtoken() {
return this.idtoken;
}
public void setIdtoken(String idtoken) {
this.idtoken = idtoken;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "user_id")
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "token_ttl", length = 19)
public Date getTokenTtl() {
return this.tokenTtl;
}
public void setTokenTtl(Date tokenTtl) {
this.tokenTtl = tokenTtl;
}
#Column(name = "ip_lock", length = 45)
public String getIpLock() {
return this.ipLock;
}
public void setIpLock(String ipLock) {
this.ipLock = ipLock;
}
}
the problem is that when I select a user using this JPA-QL: select u from User u, I get a null Set related to Tokens, even though there are associated tokens for this user.
This problem arises only when I get the JPA context (EntityManager) in a Spring 4 context. If I'm doing a test, creating the EntityManager directly (using this: Persistence.createEntityManagerFactory("unit-name");), this issue is not present.
Can anybody tell me what's the cause of my issue?
You need to use in this way
private Set<Token> tokens = new HashSet<Token>(0);
Create the Getter Setter accordingley
#OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
public Set<Token> getTokens() {
return this.tokens;
}
public void setTokens(Set<Token>tokens) {
this.tokens = tokens;
}
The problem is related to a bug from OpenJPA.
When in OpenJPA you create a bidirectional #OneToMany relationship with FetchType.EAGER fetch type, the bug comes up by not being able to create this relation. The bug is fixed in some versions. Seems to affect versions 2.1.0, 2.2.2, 2.3.0 and 2.4.0.
References:
https://issues.apache.org/jira/browse/OPENJPA-2505
Spring Data JPA OneToMany and ManyToOne give me JpaSystemException