How should I map my one table to another using JPARepositoy? - java

I have a table schema like this. Notification can be of 2 types : twitter or fb
For each notification, there will be 1 row in notification table and 1 in either twitter_post/ fb_post.
Each table have auto sequence id generator.
FBPost and TwitterPost is mapped via notification_id (PK)
I have created entity class like this:
#Entity
#Table(name = "notification")
public class Notification {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "not_id_sequence")
private String id;
#Column(name = "description")
private String description;
#OneToOne(mappedBy = "notification")
private FBPost fbPost;
#OneToOne(mappedBy = "notification")
private TwitterPost twitterPost;
}
#Entity
#Table(name = "fb_post")
public class FBPost {
#Id
#Column(name = "post_id")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "post_fid_sequence")
private Long postId;
#Column(name = "post_content")
private String postContent;
#OneToOne
private Notification notification;
}
#Entity
#Table(name = "twitter_post")
public class TwitterPost {
#Id
#Column(name = "post_id")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "post_tid_sequence")
private Long postId;
#Column(name = "post_content")
private String postContent;
#OneToOne
private Notification notification;
}
I am using JpaRepository to save into the database. But not getting any row into fb_post or twitter_post table.
Am i doing it wrong in entity class.

Try adding #JoinColumn(name = "notification_id", referencedColumnName = "notification_id") below #oneToOne in TwitterPost and FBPost class for the notification variable

Looks like you are missing cascade. Try to add cascade = CascadeType.ALL into #OneToOne of the parent entity - Notification:
#Entity
#Table(name = "notification")
public class Notification {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "not_id_sequence")
private String id;
#Column(name = "description")
private String description;
#OneToOne(mappedBy = "notification", cascade = CascadeType.ALL)
private FBPost fbPost;
#OneToOne(mappedBy = "notification", cascade = CascadeType.ALL)
private TwitterPost twitterPost;
}
For more information I would recommend to read hot to map one-to-one relationship.

Related

Spring Data JPA child entity missing parent ID after transitive save

I have the following class structure
#Entity
#Data // lombok
public class Entity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "entity_details_id", referencedColumnName = "id")
#JsonManagedReference(value = "entityDetails")
private EntityDetails entityDetails;
}
#Entity
#Data
public class EntityDetails {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#OneToOne(mappedBy = "entityDetails")
#JsonBackReference(value = "entityDetails")
private Entity entity;
// Some more fields
#OneToMany(mappedBy = "entityDetails", cascade = CascadeType.ALL, orphanRemoval = true)
#JsonManagedReference(value = "childEntityDetails")
private List<Child> childList;
}
#Entity
#Data
public class Child {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "description")
private String description;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "entity_details_id")
#JsonBackReference(value = "childEntityDetails)
private EntityDetails entityDetails;
}
Assume I have an Entity object with the following structure:
Entity{
id: null,
entityDetails: {
id: null,
childList: [
{ id: null, description: "ch1" },
{ id: null, description: "ch2" }
]
}
}
When I call entityRepository.save(entity), all the objects are persisted, but the Child table does not have a value for entity_details_id. The other values are correct (I do have Entity.entity_details_id correctly set), but this one does not work. I'm not sure if I'm missing something or if I'm just doing it wrong.

How to set parent entity in child entity object without constructor and setter method in hibernate?

I have two entities VacationTour and vacationTourDestinations. One tour can have multiple destinations. I want to save tour and destinations in the db using save() method of crudRepository with single save call. I don't want to manually set tour in the destination object. But I need the id of tour in destination as foreign key. Is this feasible?
VacationTourDestination.class
#Entity
#Table(name = "vacationTourDestinations")
public class VacationTourDestination {
#Id
#Column(name = "Id")
#GeneratedValue(strategy = GenerationType.AUTO)
protected int id;
#JoinColumn(name = "TourId")
#ManyToOne(fetch = FetchType.LAZY)
VacationTour tour;
#JoinColumn(name = "Country")
#ManyToOne
private Country country;
#Column(name = "destination")
String destination;
}
VacationTour.class
#Entity
#Table(name = "vacationTours")
public class VacationTour {
#Id
#Column(name = "Id")
#GeneratedValue(strategy = GenerationType.AUTO)
protected int id;
#Column(name = "adult")
int adult;
#Column(name = "child")
int child;
#Column(name = "infant")
int infant;
#Column(name = "termsAndConditions")
String TAC;
#OneToMany(mappedBy = "tour",cascade = CascadeType.ALL,orphanRemoval = true)
protected List<VacationTourDestination> tourDestinations;
}

How to create transition table

I have two table Movie and Actor
#Entity
#Table(name="movie")
#Data
public class Movie {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(nullable = false, unique = true)
private Integer MovieId;
......
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "actorId", referencedColumnName = "actorId")
private Actor actor;
}
#Entity
#Table(name = "actor")
#Data
public class Actor {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(nullable = false, unique = true)
private Integer actorId;
private String firstName;
private String lastName;
#OneToMany(mappedBy = "actor", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Movie> actorMovies = new ArrayList<>();
}
Now in MySql database i have two table but I need transiet table movie_actor. Now I have Movie table and column actorId and insert only one id. I want to have relation that One Movie have many Actors.

How to use uniqueConstraint on referenced table column with JPA

How can I include a referenced table column in a unique constraint? I want to create a unique constraint for table Survey for columns toEmail, receipt.receiptSeries and receipt.receiptNum.
See entities below please:
Receipt
#Entity
#Table(name = "RECEIPT")
public class Receipt {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID")
private Long id;
#Column(name = "RECEIPT_SERIES")
private String receiptSeries;
#Column(name = "RECEIPT_NUM")
private String receiptNum;
}
Survey
#Entity
#Table(name = "SURVEY"}
public class Survey {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID")
private Long id;
#ManyToOne(optional = false)
#JoinColumn(name = "RECEIPT_ID")
private Receipt receipt;
#Column(name = "TO_EMAIL")
private String toEmail;
}
I've tried using the approach below with no success:
#Table(name = "SURVEY", uniqueConstraints = {
#UniqueConstraint(columnNames = {"TO_EMAIL", "RECEIPT.RECEIPT_SERIES", "RECEIPT.RECEIPT_NUM"})})
Using a composite primary key with receiptSeries and receiptNum for Receipt is not an option.
Try something like this
#Table(name="notification_status", uniqueConstraints=
arrayOf(UniqueConstraint(columnNames= arrayOf("external_user_id",
"external_organization_id",
"notification_id"))))

Joining with cross-reference table in hibernate and spring

I use hibernate and spring-data. There are two tables with many-to-many relationship.
#Entity
#Table(name = "FirstEntity")
public class FirstEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "first_entity_id")
private Long id;
#Column(name = "first_entiry_name")
private String name;
/* getters and setters are below*/
}
#Entity
#Table(name = "SecondEntity")
public class SecondEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "second_entity_id")
private Long id;
#Column(name = "second_entiry_name")
private String name;
#Column(name = "second_entiry_desc")
private String description;
/* getters and setters are below*/
}
And entity for cross-reference table.
#Entity
#Table(name = "FirstSecondEntity")
public class FirstSecondEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "first_second_entity_id")
private Long id;
#Column(name = "first_entity_id")
private Long firstEntityId;
#Column(name = "second_entity_id")
private Long secondEntityId;
/* getters and setters are below*/
}
I need SELECT like this
SELECT FirstEntity.name, SecondEntity.name, SecondEntity.description FROM SecondEntity INNER JOIN FirstSecondEntity ON SecondEntity.id = FirstSecondEntity.secondEntityId INNER JOIN User ON FirstEntity.id = FirstSecondEntity.firstEntityId
i.e. I need all records from cross-reference table where instead of ids there is actual info from entities.
Inserting this query into #Query annotation in my CrudRepository-extended class doesn't work because of
ERROR [main][org.hibernate.hql.internal.ast.ErrorCounter] Path expected for join!
So I need your help.
Your join table is all screwed up. In this case, you actually don't even need the join table as a hibernate mapping:
In Second Entity add the following list:
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "FirstSecondEntity",
joinColumns = {
#JoinColumn(name = "first_entity_id",
nullable = false,
updatable = false) },
inverseJoinColumns = {
#JoinColumn(name = "second_entity_id",
nullable = false,
updatable = false) },
)
private List<FirstEntity> firstEntities;
In FirstEntity add the following list:
#ManyToMany(fetch = FetchType.LAZY,
mappedBy = "firstEntities")
private List<SecondEntity> secondEntities;

Categories

Resources