I have created a maven project using Spring Boot with MySQL database.
I have two entity classes that have a primary key in one entity class and another one has a composite primary key.
Customer.java(Has a primary key)
#Entity
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String address;
private String gstin;
private String phoneNumber;
#CreatedDate
private Date createdDate;
#LastModifiedDate
private Date updatedDate;
//Getters and setters
}
ItemId.java (Idclass for Item.java)
public class ItemId implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Long id;
private Long billNo;
//Getters and Setters
}
Item.java (Has a composite primary key)
#Entity
#IdClass(ItemId.class)
public class Item {
#Id
private Long id;
#Id
private Long billNo;
private String particular;
private String hsnCode;
private Double quantity;
private String quantityUnit;
private Double rate;
private String rateUnit;
private Double price;
#CreatedDate
private Date createdDate;
#LastModifiedDate
private Date updatedDate;
//Getters and setters
}
here the problem is when an entity object is persisted through repository object with the id which is already there in the table, the Spring boot JPA is not throwing the error that primary key id already present or something like that. Instead the details of the object that is trying to persist are updated to the already available primary key data. The same is happening to the Composite primary key entity.
Is there something wrong on my side or should I do furthermore configurations?
Thanks in advance.
If you are using save method from CrudRepository then you need to understand that if the entity with id (primary-key) null is saved, then it will generate a new id (auto increment depending on the implementation) and save the record. However, if the entity with id that is already in the database is passed in save method then it will update the entity.
I hope you got my point.
Please have a look at this article.
Simply use .insert() function instead of .save() function
Related
I'm trying to write a controller that will function as multiple seat reservation.The Integers list is used for filtering.
My Entity looks like this:
#Entity
#Id
private movieId;
private String movieName;
private String cinemaName;
private String cinemaHall;
private Intger seatingPlace;
private boolean booked;
How Can I pass list or sets in request body to access multiple update seatingPlace. Did I modyfing Enity or connect in smthing relation?
Acutally my multipleUpdate API works using JPA Query findByMovieNameAndCinemaNameAndcinemaHall and return me list wchich
I checking isnt Empty and cheking (field boolean booked) if true so ok u can booked them.
And after that i want filter by passing List seatingPlace and change boolen to false.
Based on my understanding of your requirements, a possible solution could be creating another entity (table) MovieSeatReservation and creating a One to Many relationship from your Entity. It could look like this: (You can replace Entity class name with your real entity name)
#Entity
public class Entity {
#Id
#GeneratedValue
private Long movieId;
private String movieName;
private String cinemaName;
private String cinemaHall;
#OneToMany
private List<MovieSeatReservation> reservedSeatsStatus;
// getters and setters
}
#Entity
public class MovieSeatReservation {
#Id
#GeneratedValue
private Long id;
private boolean isReserved;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "movie_id")
private Entity entity;
// getters and setters
}
I have the following Pojo:
#Entity
#Table(name = "USER")
class User {
#Id
private long id;
private String name;
private int age;
private long lastVisited;
private long lastPlayed;
private long lastPayed;
...
}
I would like somehow if possible to map the Pojo like this:
#Entity
#Table(name = "USER")
class User {
#Id
private long id;
private String name;
private int age;
#Embedded
private UserStatistics statistics;
...
}
#Embeddable
class UserStatistics {
private long lastVisited;
private long lastPlayed;
private long lastPayed;
}
BUT, I DON'T want to move the statistics columns into a new
USER_STATISTICS table and do #OneToOne mapping.
Is there a Hibernate trick I can use here?
Thanks!
What you did is already enough, Hibernate does not require you to define fields for all columns in your table. It's rather the other way around - all non-transient fields should be reflected as columns in the corresponding table either using name defined in #Column annotation or generated using a naming convention used in hibernate configuration.
The example you presented is sufficient and will work, but I wouldn't recommend it as you can have two entities mapping single row at the same time.
I have three classes corresponding to three tables in mysql database. My classes are as follows.
#Entity
#Table(name="location")
public class Location {
private Integer locationId;
private Integer hospitalId;
private Integer regionId;
private String locationCode;
private String locationName;
private String locationType;
#Entity
#Table(name="hospital_region")
public class HospitalRegion {
private Integer regionId;
private Integer hospitalId;
private String regionCode;
private String regionName;
public enum Status{Active,Inactive}
private Status status;
#Entity
#JsonAutoDetect
#Table(name="hospital_information")
public class HospitalInformation{
private Integer hospitalId;
private String shortName;
private String name;
private Integer packageId;
private Date implementationDate;
private Date validFrom;
private Date validUpTo;
private Date lastUpload;
public enum SubscriptionType{Free,Complimentary,Paid}
private Integer totalUsers;
I am making a Web Services for a Hospital Application where one region could have multiple locations(one-to-many) and one hospital could be in multiple regions(one-to-many).
So what I want to do is make a web service that would insert the data into location table.The ideal workflow should be that I shall pass every field in Location class as a json object to insert a record into the Location table.
My Business Logic should first check for my regionId and hospitalId value passed in the json object . If the hospitalId which is passed corresponds to the value of regionId in region table, if both correspond, only then data should be saved.
So I need help about how to implement it as a Business Logic.Thanks in advance
You miss the JPA relationships concept.
Your attributes are not annotated in the 3 classes.
You need to read about:
#ManyToOne Relation
#OneToMany Relation
#OneToOne Relation
#ManyToMany Relation
See more:
JPA Foreign Key Annotation
JPA Relationships 1
JPA Relationships 2
It seems to me that there is virtually no difference between the below two ways of mapping. Here is an example base on #MapsId javadoc:
// parent entity has simple primary key
#Entity
public class Employee {
#Id long empId;
...
}
// dependent entity uses EmbeddedId for composite key
#Embeddable
public class DependentId {
String name;
long empid; // corresponds to primary key type of Employee
}
#Entity
public class Dependent {
#EmbeddedId DependentId id;
...
#MapsId("empid") // maps the empid attribute of embedded id
#ManyToOne Employee emp;
}
What if I change Dependent's mapping to:
#Entity
public class Dependent {
#EmbeddedId DependentId id;
#ManyToOne
#JoinColumn("empid", insertable=false, updatable=false)
Employee emp;
}
What is the difference of the above two approach?
So, I tested #MapsId for my usage when in the table I have only one foregin key it was no different. But for tables where I have two foregin keys to one table like ...
UserTable, and EmailTable-> #MapsId(owner)UserTable owner, #MapsId(receiver) UserTable receiver i have problems with that. Hibernate throws exceptions. So i have to back to old #JoinColumn way of doing that. That was a one differemce that I met with that adnotations.
I am using combination of both #MapsId and #JoinColumn together to avoid getting extra field getting created in DB for associating the entities. IF I ignore #JoinColumn, an extra field is getting created in DB.
#Entity
public class BookingsModel implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private SlotDateModel slotDateModelObj;
#JsonProperty
String slotnumber;
#MapsId("memberid")
#JsonBackReference
#ManyToOne
#JoinColumn(name="memberid",referencedColumnName = "memberid")
#NotNull
MemberModel memberModel;
.
.
.
}
#Entity
public class MemberModel implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#JsonProperty
#Id
String memberid;
#JsonProperty
String name;
#JsonIgnore
String phoneno;
#JsonManagedReference
#OneToMany
Set<BookingsModel> bookings;
.
.
.
}
#Embeddable
public class SlotDateModel implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
String memberid;
String slotdate;
.
.
.
}
Tables generated with #JoinColumn
Table generated when #JoinColumn is commented Can notice that the extra field "member_model_memberid" is getting added.
I have an unowned relationship in my Domain model
#Entity
public class A {
#Id
private String id;
private Key firstB;
private Key secondB;
// getters & setters
}
#Entity
public class B {
#Id
private Key id;
private String name;
// getter & setter
}
KeyFactory.createKey(B.class.getSimpleName(), name) is the way I generate the Key for class B
I save B independently from A and assign it to an instance of A some time. The problem is that after saving A both fields firstB and firstA are null.
Any idea of what I'm doing wrong?
Key objects are not persisted by default so require explicit annotation which is why you are seeing null values.
Try annotating firstB and secondB as #Enumerated (this should really be #Basic but there is a bug which prevents this from working):
#Entity
public class A {
#Id
private String id;
#Enumerated
private Key firstB;
#Enumerated
private Key secondB;
}
Update: The latest SDK and DataNucleus JARs now correctly allow the use of #Basic.