I have been trying hibernate-core-4.3.10.Final.jar to create a dummy project. I have created model class UserDetails which have one Address field which is in fact an embeddable object. In model class I have declared this field with #Embedded annotation but I haven't defined Address class as Embeddable using #Embeddable annotation. Still the object is being embedded in the UserDeatils entity. Is #Embeddable annotation optional?? Is #Embedded annotation sufficient for hibernate to do the mapping accordingly?
Following are the code snippets:-
/** UserDetails Class **/
package com.st.hibernate.models;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
#Entity
#Table(name="USER_DETAILS")
public class UserDetails {
#Id
#Column(name="USER_ID")
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
#Column(name="USER_NAME")
#Transient
private String userName;
#Embedded
private Address address;
/**
* #return the address
*/
public Address getAddress() {
return address;
}
/**
* #param address the address to set
*/
public void setAddress(Address address) {
this.address = address;
}
#Temporal(TemporalType.DATE)
private Date currentDate;
#Lob // Large Objects----> CLob/BLob---->Character/Byte Larger Object
private String description;
/**
* #return the description
*/
public String getDescription() {
return description;
}
/**
* #param description the description to set
*/
public void setDescription(String description) {
this.description = description;
}
/**
* #return the currentDate
*/
public Date getCurrentDate() {
return currentDate;
}
/**
* #param currentDate the currentDate to set
*/
public void setCurrentDate(Date currentDate) {
this.currentDate = currentDate;
}
/**
* #return the id
*/
public int getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(int id) {
this.id = id;
}
/**
* #return the userName
*/
public String getUserName() {
return userName;
}
/**
* #param userName the userName to set
*/
public void setUserName(String userName) {
this.userName = userName;
}
}
and Address Class:-
package com.st.hibernate.models;
public class Address {
private String pincode;
private String city;
private String state;
/**
* #return the pincode
*/
public String getPincode() {
return pincode;
}
/**
* #param pincode the pincode to set
*/
public void setPincode(String pincode) {
this.pincode = pincode;
}
/**
* #return the city
*/
public String getCity() {
return city;
}
/**
* #param city the city to set
*/
public void setCity(String city) {
this.city = city;
}
/**
* #return the state
*/
public String getState() {
return state;
}
/**
* #param state the state to set
*/
public void setState(String state) {
this.state = state;
}
}
Thanks in advance.
Related
I am using the #Autowire annotation (Spring Maven Project). The following webservice/api works fine. Until I add the #Autowire annotation in post.java.
Project Path / Files:
pcbackend > visitor > pom.xml
pcbackend > visitor > src > main > visitor > Application.java
pcbackend > visitor > src > main > visitor > newvisitor.java
pcbackend > visitor > src > main > visitor > visitorrepository.java
pcbackend > visitor > src > main > visitor > post.java
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath />
<!-- lookup parent from repository -->
</parent>
<groupId>com.pc</groupId>
<artifactId>visitor</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>14</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.12</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.1.10.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<source>14</source>
<target>14</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
package com.pc.visitor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication()
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
package com.pc.visitor;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.validation.constraints.NotBlank;
#Entity
#Table(name = "visitors")
public class newvisitor {
#NotBlank
private String firstname;
#NotBlank
private String lastname;
#NotBlank
private String month;
#NotBlank
private String day;
#NotBlank
private String year;
#NotBlank
private String socialsecuritynumber;
#NotBlank
private String street1;
private String street2;
#NotBlank
private String city;
#NotBlank
private String state;
#NotBlank
private String zip;
#NotBlank
private String phone;
#NotBlank
private String email;
public newvisitor(){
super();
}
public newvisitor(String firstname, String lastname, String month, String day, String year, String socialsecuritynumber, String street1, String street2, String city, String state, String zip, String phone, String email) {
super();
this.firstname = firstname;
this.lastname = lastname;
this.month = month;
this.day = day;
this.day = year;
this.day = socialsecuritynumber;
this.day = street1;
this.day = street2;
this.day = city;
this.day = state;
this.day = zip;
this.day = phone;
this.day = email;
}
/**
* #return String return the firstname
*/
public String getFirstname() {
return firstname;
}
/**
* #param firstname the firstname to set
*/
public void setFirstname(String firstname) {
this.firstname = firstname;
}
/**
* #return String return the lastname
*/
public String getLastname() {
return lastname;
}
/**
* #param lastname the lastname to set
*/
public void setLastname(String lastname) {
this.lastname = lastname;
}
/**
* #return String return the month
*/
public String getMonth() {
return month;
}
/**
* #param month the month to set
*/
public void setMonth(String month) {
this.month = month;
}
/**
* #return String return the day
*/
public String getDay() {
return day;
}
/**
* #param day the day to set
*/
public void setDay(String day) {
this.day = day;
}
/**
* #return String return the year
*/
public String getYear() {
return year;
}
/**
* #param year the year to set
*/
public void setYear(String year) {
this.year = year;
}
/**
* #return String return the socialsecuritynumber
*/
public String getSocialsecuritynumber() {
return socialsecuritynumber;
}
/**
* #param socialsecuritynumber the socialsecuritynumber to set
*/
public void setSocialsecuritynumber(String socialsecuritynumber) {
this.socialsecuritynumber = socialsecuritynumber;
}
/**
* #return String return the street1
*/
public String getStreet1() {
return street1;
}
/**
* #param street1 the street1 to set
*/
public void setStreet1(String street1) {
this.street1 = street1;
}
/**
* #return String return the street2
*/
public String getStreet2() {
return street2;
}
/**
* #param street2 the street2 to set
*/
public void setStreet2(String street2) {
this.street2 = street2;
}
/**
* #return String return the city
*/
public String getCity() {
return city;
}
/**
* #param city the city to set
*/
public void setCity(String city) {
this.city = city;
}
/**
* #return String return the state
*/
public String getState() {
return state;
}
/**
* #param state the state to set
*/
public void setState(String state) {
this.state = state;
}
/**
* #return String return the zip
*/
public String getZip() {
return zip;
}
/**
* #param zip the zip to set
*/
public void setZip(String zip) {
this.zip = zip;
}
/**
* #return String return the phone
*/
public String getPhone() {
return phone;
}
/**
* #param phone the phone to set
*/
public void setPhone(String phone) {
this.phone = phone;
}
/**
* #return String return the email
*/
public String getEmail() {
return email;
}
/**
* #param email the email to set
*/
public void setEmail(String email) {
this.email = email;
}
}
package com.pc.visitor;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface visitorrepository extends JpaRepository<newvisitor, Long> {
}
package com.pc.visitor;
import javax.validation.Valid;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Autowired;
#CrossOrigin(origins = "http://localhost:4200")
#RestController
public class post {
//#Autowired
visitorrepository visitorrepository;
#PostMapping("/post")
public void insert(#Valid #RequestBody newvisitor newvisitor) {
}
}
APPLICATION FAILED TO START
***************************
Description:
Field visitorrepository in com.pc.visitor.post required a bean of type 'com.pc.visitor.visitorrepository' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.pc.visitor.visitorrepository' in your configuration.
I have a feeling that I am suppose to be using some of these other annotations like #service, #component, #controller, #configuration, or even #componentscan etc. I just can't figure out where to list these things.
Any ideas as to what I need to do? Like I said, everything works perfect with the #Autowired commented out.
Thoughts?
An #Id annotation was required in my newvisitor.java file/class.
package com.pc.visitor;
import javax.validation.constraints.NotBlank;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "visitors")
public class newvisitor {
#Id
private long id;
#NotBlank
private String firstname;
#NotBlank
private String lastname;
#NotBlank
private String month;
#NotBlank
private String day;
#NotBlank
private String year;
#NotBlank
private String socialsecuritynumber;
#NotBlank
private String street1;
private String street2;
#NotBlank
private String city;
#NotBlank
private String state;
#NotBlank
private String zip;
#NotBlank
private String phone;
#NotBlank
private String email;
public newvisitor(){
super();
}
public newvisitor(String firstname, String lastname, String month, String day, String year, String socialsecuritynumber, String street1, String street2, String city, String state, String zip, String phone, String email) {
super();
this.firstname = firstname;
this.lastname = lastname;
this.month = month;
this.day = day;
this.day = year;
this.day = socialsecuritynumber;
this.day = street1;
this.day = street2;
this.day = city;
this.day = state;
this.day = zip;
this.day = phone;
this.day = email;
}
/**
* #return String return the firstname
*/
public String getFirstname() {
return firstname;
}
/**
* #param firstname the firstname to set
*/
public void setFirstname(String firstname) {
this.firstname = firstname;
}
/**
* #return String return the lastname
*/
public String getLastname() {
return lastname;
}
/**
* #param lastname the lastname to set
*/
public void setLastname(String lastname) {
this.lastname = lastname;
}
/**
* #return String return the month
*/
public String getMonth() {
return month;
}
/**
* #param month the month to set
*/
public void setMonth(String month) {
this.month = month;
}
/**
* #return String return the day
*/
public String getDay() {
return day;
}
/**
* #param day the day to set
*/
public void setDay(String day) {
this.day = day;
}
/**
* #return String return the year
*/
public String getYear() {
return year;
}
/**
* #param year the year to set
*/
public void setYear(String year) {
this.year = year;
}
/**
* #return String return the socialsecuritynumber
*/
public String getSocialsecuritynumber() {
return socialsecuritynumber;
}
/**
* #param socialsecuritynumber the socialsecuritynumber to set
*/
public void setSocialsecuritynumber(String socialsecuritynumber) {
this.socialsecuritynumber = socialsecuritynumber;
}
/**
* #return String return the street1
*/
public String getStreet1() {
return street1;
}
/**
* #param street1 the street1 to set
*/
public void setStreet1(String street1) {
this.street1 = street1;
}
/**
* #return String return the street2
*/
public String getStreet2() {
return street2;
}
/**
* #param street2 the street2 to set
*/
public void setStreet2(String street2) {
this.street2 = street2;
}
/**
* #return String return the city
*/
public String getCity() {
return city;
}
/**
* #param city the city to set
*/
public void setCity(String city) {
this.city = city;
}
/**
* #return String return the state
*/
public String getState() {
return state;
}
/**
* #param state the state to set
*/
public void setState(String state) {
this.state = state;
}
/**
* #return String return the zip
*/
public String getZip() {
return zip;
}
/**
* #param zip the zip to set
*/
public void setZip(String zip) {
this.zip = zip;
}
/**
* #return String return the phone
*/
public String getPhone() {
return phone;
}
/**
* #param phone the phone to set
*/
public void setPhone(String phone) {
this.phone = phone;
}
/**
* #return String return the email
*/
public String getEmail() {
return email;
}
/**
* #param email the email to set
*/
public void setEmail(String email) {
this.email = email;
}
}
1.
You may use Spring Initializr, which generates Spring Boot project structure.
You need to add these dependencies at least:
Spring Web
Spring Data JPA
Validation (If using 2.3.0 or later)
MySQL Driver
Using this generated codes, pom.xml will be fixed.
(Note: Spring Boot uses Hibernate as JPA implementation by default, not EclipseLink.)
2.
JPA Entity needs an identifier(primary key).
you have decided that identifier type of newvisitor is Long
public interface visitorrepository extends JpaRepository<newvisitor, Long> {
}
, so newvisitor needs Long type field decorated by #Id annotation.
For example:
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
public class newvisitor {
#Id
#GeneratedValue
private Long id;
...
A couple of things that might help:
The package structure presented in the question if not compliant with maven conventions:
You should use:
src/main/java/com/pc/visitor
And place all the files there
Name classes in accordance with Java Naming conventions. Case matters:
newvisitor --> NewVisitor
post --> Post
visitorrepository --> VisitorRepository
Put your package inside src/main/java
Follow java naming convention to create class name.
Spring data JPA by default uses Hibernate though that could not be the reason to through #Autowire error.
Entity class should have a field marked as #Id.
I am trying to create a in memory database in spring boot... Still learning about spring boot and databases. How would I create an in memory database for this.
I want to create an in memory database with 3 REST endpoints...
This is what I've done so far:
package com.jason.spring_boot;
/**
* The representational that holds all the fields
* and methods
* #author Jason Truter
*
*/
public class Employee {
private final long id;
private final String name;
private final String surname;
private final String gender;
public Employee(long id, String name, String surname, String gender){
this.id = id;
this.name = name;
this.surname = surname;
this.gender = gender;
}
public long getId() {
return id;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
public String getGender() {
return gender;
}
}
package com.jason.spring_boot;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* The resource controller handles requests
* #author Jason Truter
*
*/
#Controller
#RequestMapping("/employee")
public class EmployeeController {
private final AtomicLong counter = new AtomicLong();
/**
* GET method will request and return the resource
*/
#RequestMapping(method=RequestMethod.GET)
public #ResponseBody Employee getEmployee(#RequestParam(value = "name", defaultValue = "Stranger") String name,
String surname, String gender){
return new Employee(counter.getAndIncrement(), name, surname, gender);
}
}
package com.jason.spring_boot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
My DTO is being stored using JPA Hibernate and I'm able to store the other fields but having trouble trying to store this relationship for the user. The userRoleSet HashSet has ENUMs that represent what roles that user has. Some users with have no roles while someone will have 1 to 3 roles. Each role is different. How would I got about representing this in my database and using JPA? At the moment, the #ManyToMany doesn't work, I miss be missing something else? Essentially, I need to be able to query that specific user in the database and have it return the roles that is assigned to that user.
UserType Enums
public enum UserType
{
ALPHA,BRAVO,CHARLIE
}
Default User DTO JPA
#Entity
#Table(name = "users")
public class DefaultUser implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id")
private long user_id;
#Column(name = "user_name")
private String user_name;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "password")
private String password;
#ManyToMany
private Set<UserType> userRoleSet = new HashSet<UserType>();
/**
* #return the userTypes
*/
public Set<UserType> getUserTypes()
{
return userRoleSet;
}
/**
*
* #param userTypes
* the userTypes to set
*/
public void setUserTypes(Set<UserType> userTypes)
{
this.userRoleSet = userTypes;
}
/**
* #return the user_id
*/
public long getUser_id()
{
return user_id;
}
/**
* #return the user_name
*/
public String getUser_name()
{
return user_name;
}
/**
* #return the firstName
*/
public String getFirstName()
{
return firstName;
}
/**
* #return the lastName
*/
public String getLastName()
{
return lastName;
}
/**
* #return the password
*/
public String getPassword()
{
return password;
}
/**
* #param user_id
* the user_id to set
*/
public void setUser_id(long user_id)
{
this.user_id = user_id;
}
/**
* #param user_name
* the user_name to set
*/
public void setUser_name(String user_name)
{
this.user_name = user_name;
}
/**
* #param firstName
* the firstName to set
*/
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
/**
* #param lastName
* the lastName to set
*/
public void setLastName(String lastName)
{
this.lastName = lastName;
}
/**
* #param password
* the password to set
*/
public void setPassword(String password)
{
this.password = password;
}
}
The #ManyToMany annotation is used to map an association between two entities. For collections of simple types, the annotation to use is #ElementCollection.
PS: you always read and post the complete and exact error message you get when something "doesn't work".
I'm trying to create a #OneToMany relationship in the same entity. Here is a sample code:
#Entity
public class Client extends Model{
private static final long serialVersionUID = 1L;
public Client(String username, String email) {
super();
this.username = username;
this.email = email;
}
#Id
String username;
#Required
String email;
#ManyToOne
Client parent;
#OneToMany(mappedBy="parent")
Set<Client> friends = new HashSet<Client>();
static Finder<String,Client> find = new Finder<String,Client>(String.class, Client.class);
public static void create(Client regUser){
regUser.save();
}
public static Client getByUsername(String username){
return find.byId(username);
}
public void addFriend(Client relatedClient){
this.friends.add(relatedClient);
relatedClient.update();
this.update();
}
/**
* #return the username
*/
public String getUsername() {
return username;
}
/**
* #param username the username to set
*/
public void setUsername(String username) {
this.username = username;
}
/**
* #return the email
*/
public String getEmail() {
return email;
}
/**
* #param email the email to set
*/
public void setEmail(String email) {
this.email = email;
}
/**
* #return the friends
*/
public Set<Client> getFriends() {
return friends;
}
/**
* #param friends the friends to set
*/
public void setFriends(Set<Client> friends) {
this.friends = friends;
}
/**
* #return the parent
*/
public Client getParent() {
return parent;
}
/**
* #param parent the parent to set
*/
public void setParent(Client parent) {
this.parent = parent;
}
/* (non-Javadoc)
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
return "Client [username=" + username + ", email=" + email + "]";
}
}
The problem is that after adding a new friend to a Client and searching for the same Client by Id, the friend list isn't updated correctly.
I tried your entity in an existing project I have setup, and it seems to work fine for me. I'm using play 2.1.1 with java 1.7, and Scala 2.10.0. There is this issue with enhancement that could be causing your issue.
I have a Student table with an auto generated id as primary key and one to many mappings to Phone table.
My Phone table has a composite primary key PhonePK with phone number and the foreign key id to the Student table.
If I just do student.setPhones and not do phonepk.setStudent, its complaining about id cannot be null. So I am setting student.setPhones and phonePk.setStudent. But now I am getting a stackoverflow error on toString.
I really don't like setting it on both ways in the first place but don't know how to get around the id cannot be null error. I've been asking lot of people but they could not help. Could someone take a look please?
Student.java
import java.io.Serializable;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
#Entity
#SuppressWarnings("serial")
public class Student implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String fName;
private String lName;
private String mName;
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name = "id")
private Set<Phone> phones;
/**
* #return the fName
*/
public String getfName() {
return fName;
}
/**
* #return the id
*/
public int getId() {
return id;
}
/**
* #return the lName
*/
public String getlName() {
return lName;
}
/**
* #return the mName
*/
public String getmName() {
return mName;
}
/**
* #return the phones
*/
public Set<Phone> getPhones() {
return phones;
}
/**
* #param fName
* the fName to set
*/
public void setfName(final String fName) {
this.fName = fName;
}
/**
* #param id
* the id to set
*/
public void setId(final int id) {
this.id = id;
}
/**
* #param lName
* the lName to set
*/
public void setlName(final String lName) {
this.lName = lName;
}
/**
* #param mName
* the mName to set
*/
public void setmName(final String mName) {
this.mName = mName;
}
/**
* #param phones
* the phones to set
*/
public void setPhones(final Set<Phone> phones) {
this.phones = phones;
}
/**
* {#inheritDoc}
*/
#Override
public String toString() {
return String.format("Student [id=%s, fname=%s, lname=%s, mname=%s, phones=%s]",
id,
fName, lName, mName, phones);
}
}
Phone.java
import java.io.Serializable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
#Entity
#SuppressWarnings("serial")
public class Phone implements Serializable {
#EmbeddedId
private PhonePK PK;
private String color;
/**
* #return the color
*/
public String getColor() {
return color;
}
public PhonePK getPK() {
return PK;
}
/**
* #param color
* the color to set
*/
public void setColor(final String color) {
this.color = color;
}
public void setPK(final PhonePK pK) {
PK = pK;
}
/**
* {#inheritDoc}
*/
#Override
public String toString() {
return String.format("Phone [PK=%s, color=%s]", PK, color);
}
}
PhonePK.java
import java.io.Serializable;
import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
#Embeddable
#SuppressWarnings({ "serial" })
public class PhonePK implements Serializable {
#ManyToOne
#JoinColumn(name = "id", insertable = false, updatable = false)
private Student student;
private String phoneNumber;
public String getPhoneNumber() {
return phoneNumber;
}
public Student getStudent() {
return student;
}
public void setPhoneNumber(final String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public void setStudent(final Student student) {
this.student = student;
}
/**
* {#inheritDoc}
*/
#Override
public String toString() {
return String.format("PhonePK [student=%s, phoneNumber=%s]", student, phoneNumber);
}
}
Main.java
import java.util.LinkedHashSet;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class Main {
public static void main(final String args[]) {
Configuration configuration = new Configuration();
Transaction transaction = null;
configuration.addAnnotatedClass(Student.class);
configuration.addAnnotatedClass(Phone.class);
configuration.configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Student student = new Student();
student.setfName("Bob");
student.setlName("Buster");
Set<Phone> phones = new LinkedHashSet<Phone>();
Phone phone = new Phone();
phone.setColor("Black");
PhonePK phonePK = new PhonePK();
phonePK.setPhoneNumber("1111111111");
phonePK.setStudent(student); // Do not do this? But won't work (id cannot be null
error) if
// commented out??
phone.setPK(phonePK);
phones.add(phone);
student.setPhones(phones);
try {
transaction = session.beginTransaction();
System.out.println(student.toString()); // stackoverflow error!
session.save(student);
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}
It is happening because of the way you have defined toString() methods
Student's toString() is invoking Phone's toString() which is invoking PhonePK's toString() which in turn is invoking Student's toString()...causing infinite loop.
Let see how it is happening in detailed way
In Student toString() because of phones instance variable in it .it will iterate through each phone and call Phone toString()
public String toString() {
return String.format("Student [id=%s, fname=%s, lname=%s, mname=%s, phones=%s]",
id,
fName, lName, mName, phones);
}
In Phone toString() because of PK instance variable in it .it will invoke PhonePK toString()
public String toString() {
return String.format("Phone [PK=%s, color=%s]", PK, color);
}
In PhonePK toString() because of phoneNumber instance variable in it .it will invoke Phone toString()
public String toString() {
return String.format("PhonePK [student=%s, phoneNumber=%s]", student, phoneNumber);
}