JPA one_to_one relationship not retrieve the auto increment - mysql

I have 2 Mysql tables users and empires,
users
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(45) CHARACTER SET utf8 NOT NULL,
`password` varchar(12) CHARACTER SET utf8 NOT NULL,
`country` varchar(25) CHARACTER SET utf8 NOT NULL,
`activated` tinyint(3) unsigned NOT NULL DEFAULT '0',
`activationcode` varchar(45) CHARACTER SET utf8 NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `email_UNIQUE` (`email`),
KEY `email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
and empires
CREATE TABLE `empires` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`pid` int(10) unsigned NOT NULL,
`name` varchar(45) CHARACTER SET utf8 NOT NULL,
`notes` varchar(90) CHARACTER SET utf8 NOT NULL,
`world` tinyint(3) unsigned NOT NULL,
`island` smallint(5) DEFAULT NULL,
`population` int(10) unsigned DEFAULT '20',
`gold` decimal(20,0) DEFAULT '500',
`percent` decimal(9,5) DEFAULT '50.00000',
`logo` varchar(30) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
PRIMARY KEY (`id`,`pid`),
KEY `name` (`name`),
KEY `world` (`world`),
KEY `FK_pid` (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
and i have these entities :
package boddooo.entity;
import java.io.Serializable;
import javax.persistence.*;
#Entity
#Table(name="users")
#NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private int activated=1;
private String activationcode="";
private String country;
private String email;
private String password;
public User(){}
public User(int id,String email,String password,String country) {
this.id=id;
this.email=email;
this.password=password;
this.country=country;
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public int getActivated() {
return this.activated;
}
public void setActivated(int activated) {
this.activated = activated;
}
public String getActivationcode() {
return this.activationcode;
}
public void setActivationcode(String activationcode) {
this.activationcode = activationcode;
}
public String getCountry() {
return this.country;
}
public void setCountry(String country) {
this.country = country;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
}
and
package boddooo.entity;
import java.io.Serializable;
import java.math.BigDecimal;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
#Entity
#Table(name="empires")
#NamedQuery(name="Empire.findAll", query="SELECT e FROM Empire e")
public class Empire implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private int pid;
private BigDecimal gold=BigDecimal.valueOf(500);
private String logo="";
private String name;
private String notes;
private BigDecimal percent=BigDecimal.valueOf(50.0000);
private int population=10;
private int world;
private int island;
#OneToOne
#PrimaryKeyJoinColumn(name="pid")
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Empire(){}
public Empire(int id,String name,String logo,String notes,int world) {
this.id=id;
this.name=name;
this.logo=logo;
this.notes=notes;
this.world=world;
}
public int getPid() {
return pid;
}
public void setPid(int pid){
this.pid=pid;
}
public int getWorld() {
return world;
}
public void setWorld(int world) {
this.world = world;
}
public int getIsland() {
return island;
}
public void setIsland(int island) {
this.island = island;
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public BigDecimal getGold() {
return this.gold;
}
public void setGold(BigDecimal gold) {
this.gold = gold;
}
public String getLogo() {
return this.logo;
}
public void setLogo(String logo) {
this.logo = logo;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getNotes() {
return this.notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public BigDecimal getPercent() {
return this.percent;
}
public void setPercent(BigDecimal percent) {
this.percent = percent;
}
public int getPopulation() {
return this.population;
}
public void setPopulation(int population) {
this.population = population;
}
}
and this function to insert the new objets to the database
public void createUser() throws NamingException, NotSupportedException, SystemException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException{
Context icontext=new InitialContext();
ut=(UserTransaction)icontext.lookup("java:comp/UserTransaction");
ut.begin();
User user=new User();
user.setEmail(email);
user.setPassword(password);
user.setCountry(country);
em.persist(user);
Empire emp=new Empire();
emp.setName(empirename);
emp.setNotes(empirenotes);
emp.setLogo(empirelogo);
emp.setWorld(worldid);
emp.setUser(user);
em.persist(emp);
ut.commit();
}
this is one to one relationship which
empires.pid=users.id
but when i call this method it insert users and empires but the pid field in empires has 0 value instead of the auto increment value.
am i miss something? please help

#PrimaryKeyJoinColumn indicates that the field used is this entities primary key, and as such is effectively read-only. This is mostly used when you have an entity that spans multiple tables.
#JoinColumn is what you should be using as it indicates the specified column is a traditional foreign key and that you want the target value to be used to set this field.
#OneToOne
#JoinColumn(name="pid")
private User user;

You should use #JoinColumn(name="fk_id") along with #OneToOne. More details at JSR 317: JavaTM Persistence API, Version 2.0

Related

With jpa, many side of a one-to-many relationship is not getting persisted

I am having two entities having one-to-many & many-to-one relationship.
One side:
#Entity
#Table(name = "GAME_BLIND_STRUCTURE")
#Builder
#Getter
#Setter
public class GameBlindStructureEntity implements Serializable {
private static final long serialVersionUID = -7800120016594245121L;
#Id
#Column(name = "BLIND_ID")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long blindId;
#Column(name = "BLIND_STRUCTURE_NAME", unique = true)
private String blindStructureName;
#OneToMany(mappedBy = "gameBlindStructure")
private List<GameBlindStructureDetailsEntity> gameBlindStructureDetailsEntities;
}
Many-sided entity:
#Entity
#Table(name = "GAME_BLIND_STRUCTURE_DETAILS")
#Builder
#Getter
#Setter
public class GameBlindStructureDetailsEntity implements Serializable {
private static final long serialVersionUID = -7800120016594245121L;
#Id
#Column(name = "BLIND_DETAILS_ID")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long blindDetailsId;
#ManyToOne
#JoinColumn(name = "BLIND_ID")
private GameBlindStructureEntity gameBlindStructure;
#Column(name = "LEVEL")
private String level;
#Column(name = "SMALL_BLIND")
private Integer smallBlind;
#Column(name = "BIG_BLIND")
private Integer bigBlind;
#Column(name = "ANTE")
private Integer ante;
#Column(name = "TIME_BANK")
private String timeBank;
#Column(name = "MINUTES")
private Integer minutes;
}
In the service method, I am trying to persist these entities to database.
public BlindStructureResponseDto createBlindStructure(BlindStructureDto blindStructureDto) {
GameBlindStructureEntity gameBlindStructureEntity = GameBlindStructureEntity.builder()
.blindStructureName(blindStructureDto.getName())
.build();
List<BlindStructureDetailsDto> blindStructureDetailsDtos = blindStructureDto.getBlindStructureDetailsDtos();
List<GameBlindStructureDetailsEntity> gameBlindStructureDetailsEntities = new ArrayList<>();
for(BlindStructureDetailsDto blindStructureDetailsDto : blindStructureDetailsDtos) {
GameBlindStructureDetailsEntity gameBlindStructureDetailsEntity = mapper.convertToGameStructureDetailsEntity(blindStructureDetailsDto);
gameBlindStructureDetailsEntity.setGameBlindStructure(gameBlindStructureEntity);
gameBlindStructureDetailsEntities.add(gameBlindStructureDetailsEntity);
}
gameBlindStructureEntity.setGameBlindStructureDetailsEntities(gameBlindStructureDetailsEntities);
GameBlindStructureEntity savedEntity = blindStructureRepository.save(gameBlindStructureEntity);
BlindStructureResponseDto blindStructureResponseDto = BlindStructureResponseDto.builder()
.name(savedEntity.getBlindStructureName())
.blindId(savedEntity.getBlindId())
.build();
return blindStructureResponseDto;
}
Though the entity on one-side is getting persisted to the database, the many sided entity is not getting saved.
Here is the ddl script:
DROP TABLE IF EXISTS `GAME_BLIND_STRUCTURE`;
CREATE TABLE `GAME_BLIND_STRUCTURE`
( `BLIND_ID` INT AUTO_INCREMENT,
`BLIND_STRUCTURE_NAME` VARCHAR(255) NOT NULL,
PRIMARY KEY (`BLIND_ID`),
UNIQUE KEY `UNIQUE_BLIND_STRUCTURE_NAME` (`BLIND_STRUCTURE_NAME`)
) ENGINE=INNODB DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `GAME_BLIND_STRUCTURE_DETAILS`;
CREATE TABLE `GAME_BLIND_STRUCTURE_DETAILS`
(`BLIND_DETAILS_ID` INT AUTO_INCREMENT,
`BLIND_ID` INT NOT NULL,
`LEVEL` VARCHAR(255) NOT NULL,
`SMALL_BLIND` INT NOT NULL,
`BIG_BLIND` INT NOT NULL,
`ANTE` INT NOT NULL,
`TIME_BANK`VARCHAR(255) NOT NULL,
`MINUTES` INT NOT NULL,
PRIMARY KEY(`BLIND_DETAILS_ID`),
CONSTRAINT `FK_BLIND_ID` FOREIGN KEY (`BLIND_ID`) REFERENCES `GAME_BLIND_STRUCTURE` (`BLIND_ID`)
)ENGINE=INNODB DEFAULT CHARSET=latin1;
You're missing CascadeType.ALL on your #OneToMany annotation, code should be as follows:
#OneToMany(mappedBy = "gameBlindStructure", cascade = CascadeType.ALL)
private List<GameBlindStructureDetailsEntity> gameBlindStructureDetailsEntities;

Problem with relational tables MySQL. Spring Boot + Hibernate

I'm trying to make relational tables with MySQL and Hibernate.
And here is the code in IntelliJ:
DeviceEntity
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.*;
#Entity
#Table(name = "device")
public class DeviceEntity implements Serializable {
private static final long serialVersionUID = 1L;
// -- Attributes -- //
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#Column(name = "name")
private String name;
#Column(name = "type")
private String type;
#Column(name = "model")
private String model;
#Column(name = "enabled")
private Boolean enabled;
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(pattern = "dd/MM/yyyy hh:mm:ss")
#Column(name = "created_at")
private Date createdAt;
#OneToMany(fetch = FetchType.LAZY)
private List<PetitionEntity> listPetitionEntity;
// -- Contructors -- //
public DeviceEntity(){
listPetitionEntity = new ArrayList<>();
}
// -- Methods -- //
#PrePersist
public void prePersist() {
createdAt = new Date();
}
// -- Getters & Setters -- //
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public Boolean getEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public List<PetitionEntity> getListPetitionEntity() {
return listPetitionEntity;
}
public void setListPetitionEntity(List<PetitionEntity> listPetitionEntity) {
this.listPetitionEntity = listPetitionEntity;
}
}
UserEntity
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.PrePersist;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.springframework.format.annotation.DateTimeFormat;
#Entity
#Table(name = "user")
public class UserEntity implements Serializable {
private static final long serialVersionUID = 1L;
// -- Attributes -- //
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#Column(name = "uername")
private String user;
#Column(name = "password")
private String pass;
#Column(name = "name")
private String name;
#Column(name = "surname")
private String surname;
#Column(name = "enabled")
private Boolean enabled;
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(pattern = "dd/MM/yyyy hh:mm:ss")
#Column(name = "created_at")
private Date createdAt;
#OneToMany(fetch = FetchType.LAZY)
private List<PetitionEntity> listPetitionEntity;
// -- Contructors -- //
public UserEntity() {
listPetitionEntity = new ArrayList<>();
}
// -- Methods -- //
#PrePersist
public void prePersist() {
createdAt = new Date();
}
// -- Getters & Setters -- //
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public Boolean getEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public List<PetitionEntity> getListPetitionEntity() {
return listPetitionEntity;
}
public void setListPetitionEntity(List<PetitionEntity> listPetitionEntity) {
this.listPetitionEntity = listPetitionEntity;
}
}
PetitionEntity
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
#Entity
#Table(name = "petition")
public class PetitionEntity implements Serializable {
private static final long serialVersionUID = 1L;
// -- Attributes -- //
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "device_id")
private DeviceEntity device;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "user_id")
private UserEntity user;
#Column(name = "switch_on")
private Boolean switchOn;
#Column(name = "temp_ref")
private Float tempRef;
#Column(name = "mode")
private Integer mode;
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(pattern = "dd/MM/yyyy hh:mm:ss")
#Column(name = "time_to_off")
private Date timeToOff;
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(pattern = "dd/MM/yyyy hh:mm:ss")
#Column(name = "created_at")
private Date createdAt;
// -- Methods -- //
#PrePersist
public void prePersist() {
createdAt = new Date();
}
// -- Getters & Setters -- //
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public DeviceEntity getDevice() {
return device;
}
public void setDevice(DeviceEntity device) {
this.device = device;
}
public UserEntity getUser() {
return user;
}
public void setUser(UserEntity user) {
this.user = user;
}
public Boolean getSwitchOn() {
return switchOn;
}
public void setSwitchOn(Boolean switchOn) {
this.switchOn = switchOn;
}
public Float getTempRef() {
return tempRef;
}
public void setTempRef(Float tempRef) {
this.tempRef = tempRef;
}
public Integer getMode() {
return mode;
}
public void setMode(Integer mode) {
this.mode = mode;
}
public Date getTimeToOff() {
return timeToOff;
}
public void setTimeToOff(Date timeToOff) {
this.timeToOff = timeToOff;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
}
I have this tables created in MySQL workbench. Here is the code:
Device table
CREATE TABLE `device` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(80) DEFAULT NULL,
`type` varchar(80) DEFAULT NULL,
`model` varchar(80) DEFAULT NULL,
`enabled` tinyint DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
User table
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(80) DEFAULT NULL,
`password` varchar(80) DEFAULT NULL,
`name` varchar(80) DEFAULT NULL,
`surname` varchar(80) DEFAULT NULL,
`enabled` tinyint DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`uername` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Petition table
CREATE TABLE `petition` (
`id` int NOT NULL AUTO_INCREMENT,
`user_id` int DEFAULT NULL,
`device_id` int DEFAULT NULL,
`switch_on` tinyint DEFAULT NULL,
`temp_ref` float DEFAULT NULL,
`mode` int DEFAULT NULL,
`time_to_off` datetime DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_user_table_id_idx` (`user_id`),
KEY `fk_device_table_id_idx` (`device_id`),
CONSTRAINT `fk_device_table_id` FOREIGN KEY (`device_id`) REFERENCES `device` (`id`),
CONSTRAINT `fk_user_table_id` FOREIGN KEY (`user_id`) REFERENCES `db_domotic_house`.`user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
This is my application.properties:
spring.datasource.url=jdbc:mysql://localhost/domotic_house?serverTimezone=Europe/Madrid
spring.datasource.username=root
spring.datasource.password=sasa
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=none
logging.level.org.hibernate.SQL=debug
When I run the application in IntelliJ I can see in MySQL workbench that hibernate has created some new tables that I don't want.
This are the code of that tables:
device_list_petition_entity
CREATE TABLE `device_list_petition_entity` (
`device_entity_id` int NOT NULL,
`list_petition_entity_id` int NOT NULL,
UNIQUE KEY `UK_j196d5ebc0t1v3ak5xik9cfoc` (`list_petition_entity_id`),
KEY `FKl9kjtuj8w6t07u9et7u8573hg` (`device_entity_id`),
CONSTRAINT `FK5lupuetde9paakuy8b5g86vmb` FOREIGN KEY (`list_petition_entity_id`) REFERENCES `petition` (`id`),
CONSTRAINT `FKl9kjtuj8w6t07u9et7u8573hg` FOREIGN KEY (`device_entity_id`) REFERENCES `device` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
user_list_petition_entity
CREATE TABLE `user_list_petition_entity` (
`user_entity_id` int NOT NULL,
`list_petition_entity_id` int NOT NULL,
UNIQUE KEY `UK_9ce6ulb7rn1mjpqesb0set963` (`list_petition_entity_id`),
KEY `FKfk2tckk9hrc0krq0yka2bspnf` (`user_entity_id`),
CONSTRAINT `FK5sturgl5us0uw35douhvpkug9` FOREIGN KEY (`list_petition_entity_id`) REFERENCES `petition` (`id`),
CONSTRAINT `FKfk2tckk9hrc0krq0yka2bspnf` FOREIGN KEY (`user_entity_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
I don't know what I'm doing wrong. Can someone help? Thanks!

I want to implement foreign key in my Springboot project but I get the following errors

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.Tue Oct 10 17:11:14 IST 2018 There was an unexpected error (type=Internal Server Error, status=500). could not execute statement; SQL [n/a]; nested exception is org.
hibernate.exception.SQLGrammarException: could not execute statement.
STS Error:
Before changing the code
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolation
Exception
: Cannot add or update a child row: a foreign key constraint fails
(workdemo.officeinfo, CONSTRAINT idFOREIGN KEY (id) REFERENCES mytable
(id))
After implementing joincolumn
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'entityManagerFactory' defined in class path
resource [org/springframework/boot/autoconfigure/orm/jpa/
HibernateJpaConfiguration.class]: Invocation of init method failed;
nested exception is org.hibernate.AnnotationException: No identifier
specified for entity:com.infidata.modal.MyTable
POJO( value with getters and setters,also
generated value)
Office.java
package com.infidata.modal;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="officeinfo")
public class Office {
#Id
private int sno;
private String batchno;
#ManyToOne
#JoinColumn(name = "id" )
private MyTable myTable;
private String fees;
private String reciptno;
private String trainer;
public Office() {
}
public int getSno() {
return sno;
}
public void setSno(int sno) {
this.sno = sno;
}
public String getBatchno() {
return batchno;
}
public void setBatchno(String batchno) {
this.batchno = batchno;
}
public String getFees() {
return fees;
}
public void setFees(String fees) {
this.fees = fees;
}
public String getReciptno() {
return reciptno;
}
public void setReciptno(String reciptno) {
this.reciptno = reciptno;
}
public String getTrainer() {
return trainer;
}
public void setTrainer(String trainer) {
this.trainer = trainer;
}
public Office(String batchno,String fees, String reciptno,String trainer) {
super();
this.batchno = batchno;
this.fees = fees;
this.reciptno = reciptno;
this.trainer=trainer;
}
#Override
public String toString() {
return "Office [sno=" + sno + ", batchno=" + batchno + ",fees=" + fees
+ ", reciptno=" + reciptno + ",trainer=" + trainer + "]";
}
}
MyTable.java
package com.infidata.modal;
#Entity
public class MyTable {
}
Database(name of database is workdemo)
User table(Table name: mytable)
CREATE TABLE `mytable`
( `id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`mobile` varchar(10) NOT NULL,
`email` varchar(45) NOT NULL,
`college` varchar(45) NOT NULL,
`branch` varchar(45) NOT NULL,
`semester` varchar(45) NOT NULL,
`address` varchar(105) NOT NULL,
`internship` varchar(45) NOT NULL,
`batch` varchar(45) NOT NULL,
`startdate` varchar(45) NOT NULL,
`enddate` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_0900_ai_ci
Office table(Table name:office)
CREATE TABLE `office`
(`sno` int(11) NOT NULL AUTO_INCREMENT,
`batchno` varchar(45) NOT NULL,
`id` int(11) NOT NULL,
`fees` varchar(45) NOT NULL,
`reciptno` varchar(45) NOT NULL,
PRIMARY KEY (`sno`),
KEY `id_idx` (`id`),
CONSTRAINT `id` FOREIGN KEY (`id`) REFERENCES `mytable` (`id`)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
The id(foreign key) in office table should be autoincremented with reference to student id column attribute
The problem is how you defined the entity class :
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
When you use JPA, you must specify the target entity of the relationship, not the field from database.
Your definition just tells the hibernate to generate an int value which will not correspond to a real entity.
It should be something like this:
#ManyToOne
#JoinColumn(name = "id" )
private User user;
Your office object will be
#Entity
#Table(name = "officeinfo")
public class Office {
#Id
private int sno;
private String batchno;
#ManyToOne
#JoinColumn(name = "id")
private User user;
private String fees;
private String reciptno;
private String trainer;
// getters and setters;
}
Please make sure that #Id is only on sno and you don't have on another fields, otherwise it will fail with composite key exception. Please remove id from your object, it is the foreign key to User and it is handled by:
#ManyToOne
#JoinColumn(name = "id")
private User user;

JPA insert parent and child entities in the same transaction

I'm completely stuck in this matter, maybe someone can help.
I have two entities, Parent and Child. Test1Entity is the parent, Test1ChildEntity is the child. Great naming, of course. The database is Mysql, the JPA provider is Hibernate. Below are the definitions for the two entities:
#Table(name = "Test1", schema = "", catalog = "")
#Entity
public class Test1Entity {
private int id;
#Column(name = "id")
#Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
private String name;
#Column(name = "name")
#Basic
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Test1Entity that = (Test1Entity) o;
if (id != that.id) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
private Collection<Test1ChildEntity> test1ChildrenById;
#OneToMany(mappedBy = "test1ByParentId")
public Collection<Test1ChildEntity> getTest1ChildrenById() {
return test1ChildrenById;
}
public void setTest1ChildrenById(Collection<Test1ChildEntity> test1ChildrenById) {
this.test1ChildrenById = test1ChildrenById;
}
}
#Table(name = "Test1_Child", schema = "", catalog = "")
#Entity
public class Test1ChildEntity {
private int id;
#Column(name = "id")
#Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
private String name;
#Column(name = "name")
#Basic
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Test1ChildEntity that = (Test1ChildEntity) o;
if (id != that.id) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
private Test1Entity test1ByParentId;
#ManyToOne
#JoinColumn(name = "parent_id")
public Test1Entity getTest1ByParentId() {
return test1ByParentId;
}
public void setTest1ByParentId(Test1Entity test1ByParentId) {
this.test1ByParentId = test1ByParentId;
}
}
The code trying to insert one parent with one child in the same transaction is below:
#Transactional
public void createItWell(String parentName, String childName) {
Test1Entity parent = new Test1Entity();
parent.setName(parentName);
Test1ChildEntity child = new Test1ChildEntity();
child.setName(childName);
child.setTest1ByParentId(parent);
Set<Test1ChildEntity> mySet = new HashSet<>();
mySet.add(child);
parent.setTest1ChildrenById(mySet);
this.entityManager.persist(parent);
this.entityManager.persist(child);
}
I get the following exception while trying to execute this code:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`comwork`.`test1_child`, CONSTRAINT `test1_child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `Test1` (`id`))
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
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)
Inserting other entities, stand-alone (no relations involved) works perfectly fine.
The two table definitions are:
CREATE TABLE `Test1` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
LOCK TABLES `Test1` WRITE;
/*!40000 ALTER TABLE `Test1` DISABLE KEYS */;
INSERT INTO `Test1` (`id`, `name`)
VALUES
(6,'Parent');
/*!40000 ALTER TABLE `Test1` ENABLE KEYS */;
UNLOCK TABLES;
# Dump of table Test1_Child
# ------------------------------------------------------------
CREATE TABLE `Test1_Child` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(11) unsigned NOT NULL,
`name` varchar(20) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `parent_id` (`parent_id`),
CONSTRAINT `test1_child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `Test1` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I'm new to JPA, so sorry for what probably is a trivial question.
Thank you.
Try setting Cascade attribute on OneToMany relation:
#OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
private Collection<Test1ChildEntity> test1ChildrenById;
For whoever runs into this... The entity code was generated using Idea Intellij persistance generating tool.
Apparently the tool fails to annotate the #Id fields with #GeneratedValue, thus disabling id fetching after the first (parent) entity is inserted. This way the child entity was getting inserted with a 0 (obviously invalid) value for the foreign key field.
Just add the #GeneratedValue to the #Id annotated property and it works fine.

Hibernate error: Could not determine type for: com.mysql.jdbc.Blob

I'm working on a project with Hibernate and MySQL. In one of my model objects, I declared a property "image" whose type is Blob, and I used com.mysql.jdbc.Blob. But when I ran that program, an error occurred: org.hibernate.MappingException: Could not determine type for: com.mysql.jdbc.Blob, at table: SPOT, for columns: [org.hibernate.mapping.Column(image)].
Here is source code of data model:
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
#Table(name = "SPOT", catalog = "ar", uniqueConstraints = #UniqueConstraint(columnNames = "name"))
#XmlRootElement(name = "spot")
public class Spot extends BaseIdObject {
private Double axisX;
private Double axisY;
private String address;
private String spotType;
private String description;
private String phoneNumber;
private String website;
private Blob image;
#Column(name = "axis_x", precision = 22, scale = 0)
#NotNull
public Double getAxisX() {
return this.axisX;
}
public void setAxisX(Double axisX) {
this.axisX = axisX;
}
#Column(name = "axis_y", precision = 22, scale = 0)
#NotNull
public Double getAxisY() {
return this.axisY;
}
public void setAxisY(Double axisY) {
this.axisY = axisY;
}
#Column(name = "address", length = 200)
#NotNull
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
#Column(name = "spot_type", length = 50)
#NotNull
public String getSpotType() {
return this.spotType;
}
public void setSpotType(String spotType) {
this.spotType = spotType;
}
#Column(name = "description", length = 2000)
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
#Column(name = "phone_number", length = 30)
public String getPhoneNumber() {
return this.phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
And here is the corresponding DDL of table SPOT:
DROP TABLE IF EXISTS `spot`;
/*!40101 SET #saved_cs_client = ##character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `spot` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(200) DEFAULT NULL,
`AXIS_X` double NOT NULL,
`AXIS_Y` double NOT NULL,
`ADDRESS` varchar(200) DEFAULT NULL,
`SPOT_TYPE` varchar(50) NOT NULL,
`DESCRIPTION` varchar(2000) DEFAULT NULL,
`PHONE_NUMBER` varchar(30) DEFAULT NULL,
`WEBSITE` varchar(200) DEFAULT NULL,
`IMAGE` blob,
PRIMARY KEY (`ID`),
UNIQUE KEY `SPOT_ID_UNIQUE` (`ID`),
UNIQUE KEY `SPOT_NAME_UNIQUE` (`NAME`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = #saved_cs_client */;
I searched on Internet and found a suggestion of using java.sql.Blob. But when I changed to that type, another error occurred, because in my program, I did some processes with XML on that model object, so it cannot handle the interface java.sql.Blob. So what I have to do to keep the data type com.mysql.jdbc.Blob and the program still run normally with Hibernate? Thank you so much.
I'd say that it's not right to depend on the implementation details for the JDBC driver. I would review your dependency, and try to make it a soft dependency. If you really need to keep this hard dependency, you'll need to implement an UserType capable of handling com.mysql.jdbc.Blob. I don't know the details about this implementation, but you can extend Hibernate's BlobType as MySQLBlobType, and annotate your model property with #Type annotation, specifying this MySQLBlobType:
https://github.com/hibernate/hibernate-core/blob/master/hibernate-core/src/main/java/org/hibernate/type/BlobType.java
https://github.com/hibernate/hibernate-core/blob/master/hibernate-core/src/test/java/org/hibernate/test/annotations/type/Dvd.java