How to call an api and select correct optional from update method in spring mvc - api

I have been following online tutorials for MVC but have hit a snag with updating.
Have used a updateStudent() method in the controller and pass in the id, but inside the updateStudent() I have alot of optionals.
Trying to figure out how to call the api and select the optional from within the method I want it to use
Any help is appreciated
Thanks.
Controller....
public class StudentController {
public final StudentService studentService;
#Autowired
public StudentController(StudentService studentService) {
this.studentService=studentService;
}
#PutMapping(path="/updateme/{id}")
public void updateStudent(#PathVariable ("id") UUID id,#RequestBody Student student) {
studentService.updateStudent(id, student);
}
StudentService...
#Service
public class StudentService {
private final StudentDao studentDao;
//constructor
public StudentService(#Qualifier("postgres3")StudentDao studentDao) {
this.studentDao=studentDao;
}
#PutMapping
public void updateStudent(UUID id, Student student) {
Optional.ofNullable(student.getChapterProgress())
.filter(cp -> !StringUtils.isEmpty(cp))
.ifPresent(cp -> studentDao.updateChapterProgress(id, cp));
Optional.ofNullable(student.getAvgTestScore())
.filter(avg -> !StringUtils.isEmpty(avg))
.ifPresent(avg -> studentDao.updateAvgTestScore(id, avg));
Optional.ofNullable(student.getChap1Score())
.filter(c1 -> !StringUtils.isEmpty(c1))
.ifPresent(c1 -> studentDao.updateChap1Score(id, c1));
Optional.ofNullable(student.getChap2Score())
.filter(c2 -> !StringUtils.isEmpty(c2))
.ifPresent(c2 -> studentDao.updateChap2Score(id, c2));
Optional.ofNullable(student.getChap3Score())
.filter(c3 -> !StringUtils.isEmpty(c3))
.ifPresent(c3 -> studentDao.updateChap3Score(id, c3));
Optional.ofNullable(student.getChap4Score())
.filter(c4 -> !StringUtils.isEmpty(c4))
.ifPresent(c4 -> studentDao.updateChap4Score(id, c4));
Optional.ofNullable(student.getChap5Score())
.filter(c5 -> !StringUtils.isEmpty(c5))
.ifPresent(c5 -> studentDao.updateChap5Score(id, c5));
Optional.ofNullable(student.getChap6Score())
.filter(c6 -> !StringUtils.isEmpty(c6))
.ifPresent(c6 -> studentDao.updateChap6Score(id, c6));
}
StudentDataAccessService...
#Repository("postgres3")
public class StudentDataAccessService implements StudentDao {
private JdbcTemplate jdbcTemplate;
#Autowired
public StudentDataAccessService(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate= jdbcTemplate;
}
#Override
public int updateChapterProgress(UUID id, Integer chapterprogress) {
String sql = "UPDATE student SET chapterprogress = ? WHERE id = ?";
return jdbcTemplate.update(sql, chapterprogress, id);
}
#Override
public int updateAvgTestScore(UUID id, Double avg) {
String sql = "UPDATE student SET avgtestscore = ? WHERE id = ?";
return jdbcTemplate.update(sql, avg, id);
}
#Override
public int updateChap1Score(UUID id, Double chap1Score) {
String sql = "UPDATE student SET chap1score = ? WHERE id = ?";
return jdbcTemplate.update(sql, chap1Score, id);
}
#Override
public int updateChap2Score(UUID id, Double chap2Score) {
String sql = "UPDATE student SET chap2score = ? WHERE id = ?";
return jdbcTemplate.update(sql, chap2Score, id);
}
#Override
public int updateChap3Score(UUID id, Double chap3Score) {
String sql = "UPDATE student SET chap3score = ? WHERE id = ?";
return jdbcTemplate.update(sql, chap3Score, id);
}
#Override
public int updateChap4Score(UUID id, Double chap4Score) {
String sql = "UPDATE student SET chap4score = ? WHERE id = ?";
return jdbcTemplate.update(sql, chap4Score, id);
}
#Override
public int updateChap5Score(UUID id, Double chap5Score) {
String sql = "UPDATE student SET chap5score = ? WHERE id = ?";
return jdbcTemplate.update(sql, chap5Score, id);
}
#Override
public int updateChap6Score(UUID id, Double chap6Score) {
String sql = "UPDATE student SET chap6score = ? WHERE id = ?";
return jdbcTemplate.update(sql, chap6Score, id);
}
#Override
public int updateStudentById(UUID id, Student student) {
return 0;
}
StudentDao...
public interface StudentDao {
int updateStudentById(UUID id,Student student);
int updateChapterProgress(UUID id, Integer chapterprogress);
int updateAvgTestScore(UUID id, Double avg);
int updateChap1Score(UUID id, Double chap1Score);
int updateChap2Score(UUID id, Double chap2Score);
int updateChap3Score(UUID id, Double chap3Score);
int updateChap4Score(UUID id, Double chap4Score);
int updateChap5Score(UUID id, Double chap5Score);
int updateChap6Score(UUID id, Double chap6Score);

Ended up assigning each update to its own method call in the controller, thanks

Related

One to One Mapping Spring boot

Hello everyone in advance I have a problem with my one to one connection when I try to log in to the "user" I get this error
what i need is a one to one connection that does not have to be persistent that means a user can have a player but does not have to have it and the other way around
Since in my case the Minecraft server is supposed to fill the player table and the website fills the users so that they can be connected.
2020-07-27 23:06:12,537 DEBUG [http-nio-8080-exec-2] nirvanacw.de.demo.user.UserServiceImpl: --> getUserByEmail email=Test#gmx.de
2020-07-27 23:06:12,550 WARN [http-nio-8080-exec-2] org.hibernate.engine.jdbc.spi.SqlExceptionHelper: SQL Error: 42122, SQLState: 42S22
2020-07-27 23:06:12,550 ERROR [http-nio-8080-exec-2] org.hibernate.engine.jdbc.spi.SqlExceptionHelper: Feld "player0_.player" nicht gefunden
Column "player0_.player" not found; SQL statement:
select player0_.id as id1_2_1_, player0_.banned as banned2_2_1_, player0_.first_joined as first_jo3_2_1_, player0_.ip_address as ip_addre4_2_1_, player0_.last_joined as last_joi5_2_1_, player0_.player as player8_2_1_, player0_.player_name as player_n6_2_1_, player0_.uuid as uuid7_2_1_, user1_.id as id1_3_0_, user1_.active as active2_3_0_, user1_.created as created3_3_0_, user1_.email as email4_3_0_, user1_.first_name as first_na5_3_0_, user1_.last_name as last_nam6_3_0_, user1_.password as password7_3_0_, user1_.reset_password as reset_pa8_3_0_, user1_.roles as roles9_3_0_, user1_.updated as updated10_3_0_, user1_.username as usernam11_3_0_ from player player0_ left outer join user user1_ on player0_.player=user1_.id where player0_.player=? [42122-200]
2020-07-27 23:06:12,558 ERROR [http-nio-8080-exec-2] org.springframework.security.oauth2.provider.endpoint.TokenEndpoint: Handling error: InternalAuthenticationServiceException, could not prepare statement; SQL [select player0_.id as id1_2_1_, player0_.banned as banned2_2_1_, player0_.first_joined as first_jo3_2_1_, player0_.ip_address as ip_addre4_2_1_, player0_.last_joined as last_joi5_2_1_, player0_.player as player8_2_1_, player0_.player_name as player_n6_2_1_, player0_.uuid as uuid7_2_1_, user1_.id as id1_3_0_, user1_.active as active2_3_0_, user1_.created as created3_3_0_, user1_.email as email4_3_0_, user1_.first_name as first_na5_3_0_, user1_.last_name as last_nam6_3_0_, user1_.password as password7_3_0_, user1_.reset_password as reset_pa8_3_0_, user1_.roles as roles9_3_0_, user1_.updated as updated10_3_0_, user1_.username as usernam11_3_0_ from player player0_ left outer join user user1_ on player0_.player=user1_.id where player0_.player=?]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
org.springframework.security.authentication.InternalAuthenticationServiceException: could not prepare statement; SQL [select player0_.id as id1_2_1_, player0_.banned as banned2_2_1_, player0_.first_joined as first_jo3_2_1_, player0_.ip_address as ip_addre4_2_1_, player0_.last_joined as last_joi5_2_1_, player0_.player as player8_2_1_, player0_.player_name as player_n6_2_1_, player0_.uuid as uuid7_2_1_, user1_.id as id1_3_0_, user1_.active as active2_3_0_, user1_.created as created3_3_0_, user1_.email as email4_3_0_, user1_.first_name as first_na5_3_0_, user1_.last_name as last_nam6_3_0_, user1_.password as password7_3_0_, user1_.reset_password as reset_pa8_3_0_, user1_.roles as roles9_3_0_, user1_.updated as updated10_3_0_, user1_.username as usernam11_3_0_ from player player0_ left outer join user user1_ on player0_.player=user1_.id where player0_.player=?]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
User Entity :
package nirvanacw.de.demo.user;
import nirvanacw.de.demo.player.Player;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import javax.validation.constraints.Email;
import java.time.ZonedDateTime;
import java.util.Objects;
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
#GenericGenerator(name = "native", strategy = "native")
#Column(name = "id", updatable = false, nullable = false)
private Long id;
#Email
#Column(name = "email")
private String email;
#Column(name ="username")
private String username;
#Column(name ="password")
private String password;
#Column(name ="first_name")
private String firstName;
#Column(name ="last_name")
private String lastName;
#OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Player player;
#Column(name ="reset_password")
private boolean resetPassword;
#Column(name ="roles")
private String roles;
#Column(name ="active")
private boolean active;
#Column(name = "created")
private ZonedDateTime created;
#Column(name = "updated")
private ZonedDateTime updated;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public boolean isResetPassword() {
return resetPassword;
}
public void setResetPassword(boolean resetPassword) {
this.resetPassword = resetPassword;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRoles() {
return roles;
}
public void setRoles(String roles) {
this.roles = roles;
}
public boolean getActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
public Player getPlayer() {
return player;
}
public void setPlayer(Player player) {
this.player = player;
}
#PrePersist
public void onPrePersist() {
this.created = ZonedDateTime.now();
}
#PreUpdate
public void onPreUpdate() {
this.updated = ZonedDateTime.now();
}
#Override
public String toString() {
return "User{" +
"id=" + id +
", email='" + email + '\'' +
", username='" + username + '\'' +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", player=" + player +
", resetPassword=" + resetPassword +
", roles='" + roles + '\'' +
", active=" + active +
", created=" + created +
", updated=" + updated +
'}';
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return resetPassword == user.resetPassword &&
active == user.active &&
Objects.equals(id, user.id) &&
Objects.equals(email, user.email) &&
Objects.equals(username, user.username) &&
Objects.equals(password, user.password) &&
Objects.equals(firstName, user.firstName) &&
Objects.equals(lastName, user.lastName) &&
Objects.equals(player, user.player) &&
Objects.equals(roles, user.roles) &&
Objects.equals(created, user.created) &&
Objects.equals(updated, user.updated);
}
#Override
public int hashCode() {
return Objects.hash(id, email, username, password, firstName, lastName, player, resetPassword, roles, active, created, updated);
}
}
Player Entity :
import java.sql.Timestamp;
import java.util.Objects;
import java.util.UUID;
#Entity
#Table(name = "player")
public class Player {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
#GenericGenerator(name = "native", strategy = "native")
#Column(name = "id", updatable = false, nullable = false)
private Long id;
#Column(name = "uuid")
private UUID uuid;
#OneToOne
#JoinColumn(name = "player")
private User user;
#Length(max = 16)
#Column(name = "player_name")
private String userName;
#Column(name = "banned")
private boolean banned;
#Column(name = "first_joined")
private Timestamp firstJoined;
#Column(name = "last_joined")
private Timestamp lastJoined;
#Column(name = "ip_address")
private String ipAddress;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public UUID getUuid() {
return uuid;
}
public void setUuid(UUID uuid) {
this.uuid = uuid;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public boolean isBanned() {
return banned;
}
public void setBanned(boolean banned) {
this.banned = banned;
}
public Timestamp getFirstJoined() {
return firstJoined;
}
public void setFirstJoined(Timestamp firstJoined) {
this.firstJoined = firstJoined;
}
public Timestamp getLastJoined() {
return lastJoined;
}
public void setLastJoined(Timestamp lastJoined) {
this.lastJoined = lastJoined;
}
public String getIpAddress() {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
#Override
public String toString() {
return "Player{" +
"id=" + id +
", uuid=" + uuid +
", user=" + user +
", userName='" + userName + '\'' +
", banned=" + banned +
", firstJoined=" + firstJoined +
", lastJoined=" + lastJoined +
", ipAddress='" + ipAddress + '\'' +
'}';
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Player player = (Player) o;
return banned == player.banned &&
Objects.equals(id, player.id) &&
Objects.equals(uuid, player.uuid) &&
Objects.equals(user, player.user) &&
Objects.equals(userName, player.userName) &&
Objects.equals(firstJoined, player.firstJoined) &&
Objects.equals(lastJoined, player.lastJoined) &&
Objects.equals(ipAddress, player.ipAddress);
}
#Override
public int hashCode() {
return Objects.hash(id, uuid, user, userName, banned, firstJoined, lastJoined, ipAddress);
}
}
Flyway user :
Create TABLE user(
id bigint NOT NULL AUTO_INCREMENT,
email character varying(256),
username character varying(256),
password character varying(256),
reset_password boolean,
first_name character varying(50),
last_name character varying(50),
gender character varying(10),
player_id character varying(17),
active boolean,
roles character varying(40),
created TIMESTAMP,
updated TIMESTAMP,
CONSTRAINT PK_account_account_id PRIMARY KEY (id)
);
Player Flyway :
CREATE TABLE player(
id bigint NOT NULL AUTO_INCREMENT,
uuid char(36) NOT NULL,
player_name character varying (16),
user_id bigint,
banned boolean,
first_joined timestamp,
last_joined timestamp,
ip_address character varying (15),
CONSTRAINT PK_player_player_id PRIMARY KEY (id),
CONSTRAINT FK_player_user_id_user_id FOREIGN KEY (user_id) REFERENCES user(id)
);
The error is quite clear
Column "player0_.player" not found;
the player table does not have a player column
the error is here:
#OneToOne
#JoinColumn(name = "player")
private User user;
change to:
#OneToOne
#JoinColumn(name = "user_id")
private User user;
It is the column by which the join with user is established.
As a recommendation, there are configuration parameters for the JPA implementation to validate the correct modeling of the entities without the need for queries, find out how to activate it with the implementation you have chosen.

MediaStore select query returns only one row

I'm trying to develop music player, I've made a loader and adapter for my data retreiving from mediastore, but when I call query from my app it only returns one row, I don't know wat's wrong with my code, would u help me fixing that problem?
That's my loader which should return a list I'll use in another place
public static List<Song> getAllArtistSongs(Context context, long artist_id){
List<Song> ArtistSongList = new ArrayList<>();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] projection = new String[]{
"_id",
"title",
"album_id",
"album",
"artist",
"duration",
"track"
};
String sortorder = MediaStore.Audio.Media.DEFAULT_SORT_ORDER;
String selection = "is_music=1 and artist_id="+artist_id;
Cursor cursor = context.getContentResolver().query(uri, projection, selection, null, sortorder);
assert cursor != null;
if (cursor.moveToFirst()) {
do {
int trackNumber = cursor.getInt(6);
while (trackNumber >= 1000) {
trackNumber -= 1000;
}
Long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
Long albumid = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
String albumname = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
String artistname = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
int duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
ArtistSongList.add(new Song(id, title, albumid, albumname, artist_id, artistname, duration, trackNumber));
} while (cursor.moveToNext());
cursor.close();
}
return ArtistSongList;
}
And this is the adapter which I use to bind to a recyclerview
public void onBindViewHolder(#NonNull VH holder, int position) {
Song song = artistSongList.get(position);
if(song!=null){
holder.ttv.setText(song.title);
holder.dtv.setText(song.artistName);
int trackN = song.trackNumber;
if(trackN==0){
holder.ntv.setText("_");
}else holder.ntv.setText(String.valueOf(trackN));
}
}
And this is where I call the query func
private void setupAlbumList() {
System.out.println(artistId);
songList = ArtistSongLoader.getAllArtistSongs(getActivity(), artistId);
adapter = new ArtistSongAdapter(getActivity(), songList);
recy.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL));
recy.setAdapter(new ArtistSongAdapter(getActivity(), songList));
}
Thx in advance for helping
My example to retrieve all tracks:
private final String track_id = MediaStore.Audio.Media._ID;
private final String track_no = MediaStore.Audio.Media.TRACK;
private final String track_name = MediaStore.Audio.Media.TITLE;
private final String artist = MediaStore.Audio.Media.ARTIST;
private final String artist_id = MediaStore.Audio.Media.ARTIST_ID;
private final String duration = MediaStore.Audio.Media.DURATION;
private final String album = MediaStore.Audio.Media.ALBUM;
private final String composer = MediaStore.Audio.Media.COMPOSER;
private final String year = MediaStore.Audio.Media.YEAR;
private final String path = MediaStore.Audio.Media.DATA;
private final String date_added = MediaStore.Audio.Media.DATE_ADDED;
public Cursor getAllTracks(Context context) {
// gets all tracks
if (context != null) {
ContentResolver cr = context.getContentResolver();
final String[] columns = {track_id, track_no, artist, track_name,
album, duration, path, year, composer};
return cr.query(uri, columns, null, null, null);
} else {
return null;
}
}
then you have
String selection = "is_music=1"
first, you do not need is_music=1. For multiple tracks you of course need more than 1 track by the same artist
The adapter is irrelevant, the query does the selection
To return albums for an artist
public Cursor getArtistsAlbumcursor(Context context, String artistId) {
ContentResolver cr = context.getContentResolver();
final String _id = MediaStore.Audio.Media._ID;
final String album_id = MediaStore.Audio.Media.ALBUM_ID;
final String artistid = MediaStore.Audio.Media.ARTIST_ID;
final String[] columns = {_id, album_id, artistid};
if (artistId != null) {
String where = artistid + " =?";
String[] aId = {artistId};
return cr.query(uri, columns, where, aId, null);
} else {
return null;
}
}

Arraylist not displaying the right output

My main class code
{
ArrayList<Item> items = new ArrayList<Item>();
Scanner file = new Scanner(kk.class.getResourceAsStream("product.txt"));
while (file.hasNextLine()) {
String[] sp = file.nextLine().split(",");
// extract item number, description, price and type
itemNum = Integer.parseInt(sp[0]);
des = sp[1];
price = Integer.parseInt(sp[2]);
Item objt = new Item(itemNum, des, price); // Creating a new object
items.add(objt); // Adding it to the list
}
System.out.println(items);
}
output I am getting
[dada.Item#4a5d4a62, dada.Item#32be8e12, dada.Item#7c6159c4, dada.Item#5b4c92a7, dada.Item#3040c5,
My item class code
private int itemNum = 0;
private String des = "";
private int price = 0;
public Item(int i, String d, int p) {
itemNum = i;
des = d;
price = p;
}
You're printing the Item reference's address instead of the fields inside your Item object. You have print the fields inside each Item object by looping through them.
Replace this line
System.out.println(items);
with
for(Item i : items)
{
System.out.println(i.getItemNum()+" "+i.getDes()+" "+i.getPrice());
}
Change the class so that you could access your private fields
private int itemNum = 0;
private String des = "";
private int price = 0;
public Item(int i, String d, int p) {
itemNum = i;
des = d;
price = p;
}
public void setItemNum(int itemNum) {
this.itemNum = itemNum;
}
public int getItemNum() {
return itemNum;
}
public void setDes(String des) {
this.des = des;
}
public String getDes() {
return des;
}
public void setPrice(int price) {
this.price = price;
}
public int getPrice() {
return price;
}

How do you input data into a constructor from scanner?

I am trying to take a constructor(string, string, double) and set the value in it with a scanner input. any help is appreciated. The code is list below.
My programs can assign the values that i put in, but I want to be able to assign them from the keyboard and I would like to use only one constructor method to accomplish this. Thanks
I have it broken up into two classes:
import java.util.Scanner;
public class EmployeeTest
{
public static void main(String [] args)
{
Scanner input = new Scanner(System.in);
Employee employee1 = new Employee("james", "ry", 3200);
Employee employee2 = new Employee("jim" , "bob" , 2500.56 );
System.out.println("What is employyee 1's first name? ");
employee1.setFname(input.nextLine());
}
}
class Employee
{
private String fname;
private String lname;
private double pay;
public Employee(String fname, String lname, double pay)
{
this.setFname(fname);
this.lname = lname;
this.pay = pay;
System.out.println("Employee " + fname +" "+ lname + " makes $" +
+ pay + " this month and with a 10% raise, their new pay is $" + (pay * .10 + pay));
}
void setfname(String fn)
{
setFname(fn);
}
void setlname(String ln)
{
lname = ln;
}
void setpay (double sal)
{
pay = sal;
}
String getfname()
{
return getFname();
}
String getlname()
{
return lname;
}
double getpay()
{
if (pay < 0.00)
{
return pay = 0.0;
}
return pay;
}
public String getFname() {
return fname;
}
public void setFname(String fname)
{
this.fname = fname;
}
}
You can modify you EmployeeTest class something like
class EmployeeTest {
public static void main (String...arg) {
Scanner s = new Scanner(System.in);
String[] elements = null;
while (s.hasNextLine()) {
elements = s.nextLine().split("\\s+");
//To make sure that we have all the three values
//using which we want to construct the object
if (elements.length == 3) {
//call to the method which creates the object needed
//createObject(elements[0], elements[1], Double.parseDouble(elements[2]))
//or, directly use these values to instantiate Employee object
} else {
System.out.println("Wrong values passed");
break;
}
}
s.close();
}
}

Composite primary key with a Foreign key not working in MySQL

My Phone table has a composite primary of phone number and id. id is also a foreign key to the Student table.
I am seeing the below error when I run it.
23:30:28,228 ERROR SqlExceptionHelper:147 - Column 'id' cannot be null
org.hibernate.exception.ConstraintViolationException: could not execute statement
Schema:
Table: student
Columns:
id (PK)
fName
lName
mName
Table: Phone
Columns:
phoneNumber (PK)
color
id(PK)(FK references to Student id)
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;
}
}
Phone.java
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
#IdClass(PhonePK.class)
#Entity
#SuppressWarnings("serial")
public class Phone implements Serializable {
#Id
private String phoneNumber;
// #Id
// #ManyToOne
// #JoinColumn(name = "id", insertable = false, updatable = false)
// private String id;
#Id
#ManyToOne
#JoinColumn(name = "id", insertable = false, updatable = false)
private Student student;
// public String getId() {
// return id;
// }
//
// public void setId(String id) {
// this.id = id;
// }
private String color;
/**
* #return the color
*/
public String getColor() {
return color;
}
/**
* #return the phoneNumber
*/
public String getPhoneNumber() {
return phoneNumber;
}
/**
* #return the student
*/
public Student getStudent() {
return student;
}
/**
* #param color
* the color to set
*/
public void setColor(final String color) {
this.color = color;
}
/**
* #param phoneNumber
* the phoneNumber to set
*/
public void setPhoneNumber(final String phoneNumber) {
this.phoneNumber = phoneNumber;
}
/**
* #param student
* the student to set
*/
public void setStudent(final Student student) {
this.student = student;
}
}
PhonePK.java
import java.io.Serializable;
#SuppressWarnings("serial")
public class PhonePK implements Serializable {
private String phoneNumber;
//private String id;
private Student student;
// public String getId() {
// return id;
// }
//
// public void setId(String id) {
// this.id = id;
// }
/**
* #return the phoneNumber
*/
public String getPhoneNumber() {
return phoneNumber;
}
/**
* #return the student
*/
public Student getStudent() {
return student;
}
/**
* #param phoneNumber
* the phoneNumber to set
*/
public void setPhoneNumber(final String phoneNumber) {
this.phoneNumber = phoneNumber;
}
/**
* #param student
* the student to set
*/
public void setStudent(final Student student) {
this.student = student;
}
#Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
PhonePK other = (PhonePK) obj;
if (phoneNumber == null) {
if (other.phoneNumber != null) {
return false;
}
} else if (!phoneNumber.equals(other.phoneNumber)) {
return false;
}
if (student == null) {
if (other.student != null) {
return false;
}
} else if (!student.equals(other.student)) {
return false;
}
// if (id == null) {
// if (other.id != null) {
// return false;
// }
// } else if (!id.equals(other.id)) {
// return false;
// }
return true;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((phoneNumber == null) ? 0 : phoneNumber.hashCode());
result = prime * result + ((student == null) ? 0 : student.hashCode());
// result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
}
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">pwd</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="hibernate.connection.username">user</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.pool_size">1</property>
<property name="hbm2ddl.auto">create</property>
</session-factory>
</hibernate-configuration>
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.addAnnotatedClass(PhonePK.class);
configuration.configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
System.out.println("Session Factory!!!!" + sessionFactory);
Session session = sessionFactory.openSession();
Student student = new Student();
student.setfName("Bob");
student.setlName("Buster");
Set<Phone> phones = new LinkedHashSet<Phone>();
Phone ph1 = new Phone();
ph1.setColor("Black");
ph1.setPhoneNumber("1111111111");
Phone ph2 = new Phone();
ph2.setColor("Blue");
ph2.setPhoneNumber("2222222222");
phones.add(ph1);
phones.add(ph2);
student.setPhones(phones);
try {
transaction = session.beginTransaction();
session.save(student);
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}
Console output:
23:30:24,291 INFO SchemaExport:343 - HHH000227: Running hbm2ddl schema export
23:30:24,296 DEBUG SQL:104 - alter table Phone drop foreign key
FK_aoj0eivd0ap3drxnoyk4xj10q
23:30:25,613 DEBUG SQL:104 - drop table if exists Phone
23:30:25,967 DEBUG SQL:104 - drop table if exists Student
23:30:26,230 DEBUG SQL:104 - create table Phone (phoneNumber varchar(255) not null,
color varchar(255), id integer not null, primary key (phoneNumber, id))
23:30:26,731 DEBUG SQL:104 - create table Student (id integer not null auto_increment,
fName varchar(255), lName varchar(255), mname varchar(255), primary key (id))
23:30:26,792 DEBUG SQL:104 - alter table Phone add index FK_aoj0eivd0ap3drxnoyk4xj10q
(id), add constraint FK_aoj0eivd0ap3drxnoyk4xj10q foreign key (id) references Student
(id)
23:30:27,352 INFO SchemaExport:405 - HHH000230: Schema export complete
Session Factory!!!!org.hibernate.internal.SessionFactoryImpl#548997d1
23:30:27,823 DEBUG SQL:104 - insert into Student (fName, lName, mname) values (?, ?, ?)
23:30:27,886 TRACE BasicBinder:84 - binding parameter [1] as [VARCHAR] - Bob
23:30:27,887 TRACE BasicBinder:84 - binding parameter [2] as [VARCHAR] - Buster
23:30:27,888 TRACE BasicBinder:72 - binding parameter [3] as [VARCHAR] - <null>
23:30:28,005 DEBUG SQL:104 - select phone_.phoneNumber, phone_.id, phone_.color as
color2_0_ from Phone phone_ where phone_.phoneNumber=? and phone_.id=?
23:30:28,009 TRACE BasicBinder:84 - binding parameter [1] as [VARCHAR] - 1111111111
23:30:28,010 TRACE BasicBinder:72 - binding parameter [2] as [INTEGER] - <null>
23:30:28,102 DEBUG SQL:104 - select phone_.phoneNumber, phone_.id, phone_.color as
color2_0_ from Phone phone_ where phone_.phoneNumber=? and phone_.id=?
23:30:28,103 TRACE BasicBinder:84 - binding parameter [1] as [VARCHAR] - 2222222222
23:30:28,104 TRACE BasicBinder:72 - binding parameter [2] as [INTEGER] - <null>
23:30:28,222 DEBUG SQL:104 - insert into Phone (color, phoneNumber, id) values (?, ?,
?)
23:30:28,223 TRACE BasicBinder:84 - binding parameter [1] as [VARCHAR] - Black
23:30:28,224 TRACE BasicBinder:84 - binding parameter [2] as [VARCHAR] - 1111111111
23:30:28,224 TRACE BasicBinder:72 - binding parameter [3] as [INTEGER] - <null>
23:30:28,227 WARN SqlExceptionHelper:145 - SQL Error: 1048, SQLState: 23000
23:30:28,228 ERROR SqlExceptionHelper:147 - Column 'id' cannot be null
org.hibernate.exception.ConstraintViolationException: could not execute statement
at
org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert
(SQLExceptionTypeDelegate.java:74)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert
(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert
(SqlExceptionHelper.java:125)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert
(SqlExceptionHelper.java:110)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate
(ResultSetReturnImpl.java:136)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch
(NonBatchingBatch.java:58)
at org.hibernate.persister.entity.AbstractEntityPersister.insert
(AbstractEntityPersister.java:3067)
at org.hibernate.persister.entity.AbstractEntityPersister.insert
(AbstractEntityPersister.java:3509)
at org.hibernate.action.internal.EntityInsertAction.execute
(EntityInsertAction.java:88)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:377)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:369)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:286)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions
(AbstractFlushingEventListener.java:339)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush
(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.
beforeTransactionCommit
(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit
(AbstractTransactionImpl.java:175)
at Main.main(Main.java:49)
Caused by:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Column 'id' cannot be null
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4187)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4119)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate
(ResultSetReturnImpl.java:133)
... 14 more
23:30:28,323 INFO AbstractBatchImpl:195 - HHH000010:
On release of batch it still contained JDBC statements
you can create embeddale Primary key class.
#Embeddable
public class Phone_pk implements Serializable{
#ManyToOne(targetEntity=Student.class)
#JoinColumn(name="id", referencedColumnName="id")
#ForeignKey(name="Student_Phone_FK")
private Student student;
private String phoneNumber;
}
And use this as primary key in your phone class
#EmbeddedId
private Phone_pk PK;