Manytoone mapping for two tables to the single entity - spring-boot

Class A{
private int campid;
private string name;
}
Class B {
Private int campid;
Private string name;
}`
Class combo{
private int id;
private string phonenumber;
}
I'm trying like this
Class A{
private int campid;
private string name;
#OneToMany(targetEntity = Combo.class,mappedBy ="a",fetch = FetchType.LAZY,cascade=CascadeType.ALL )
private Combo combo;
}
Class B {
Private int campid;
Private string name;
#OneToMany(targetEntity = Combo.class,mappedBy ="b",fetch = FetchType.LAZY,cascade=CascadeType.ALL )
private Combo combo;
}`
Class combo{
private int id;
private string phonenumber;
#ManyToOne
#JoinColumn(name = "Camp_Id_fk",insertable=true, updatable=true)
private A a;
#ManyToOne
#JoinColumn(name = "Camp_Id_fk",insertable=true, updatable=true)
private B b;
}
want to store the campid of class A and campid class B as the foreign key in the combo table. One campid can have multiple phone numbers.
I want to do this in spring jpa..I'm not understanding how to do it

#Entity
#Table(name = "a")
public class A {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "camp_id")
private Long campid;
#Column(name = "name")
private String name;
#Column
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
#JoinTable(name = "a_combo",
joinColumns = #JoinColumn(name = "camp _id"),
inverseJoinColumns = #JoinColumn(name = "id"))
private Set<Combo> comboSet = new HashSet<>();
}
And same for B class

Related

One to one bi direction mapping is not working

My code contains two entities, that have relation with each other.
Student Class :
#Entity
#Table(name = "student")
public class Student {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "email")
private String email;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "student_detail_id")
private StudentDetail studentDetail;
public Student() {}
//getters setters
StudentDetail Class :
#Entity
#Table(name = "student_detail")
public class StudentDetail {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "college")
private String college;
#Column(name = "no_of_problems_solved")
private int noOfProblemsSolved;
public StudentDetail() {}
#Column(name = "college")
private String college;
#Column(name = "no_of_problems_solved")
private int noOfProblemsSolved;
public StudentDetail() {}
Why is the one to one bi direction mapping not working?
In Student_Detail you have to specify #OntToOne Annotation also.
#Entity
#Table(name = "student_detail")
public class StudentDetail {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "college")
private String college;
#Column(name = "no_of_problems_solved")
private int noOfProblemsSolved;
#OneToOne(mappedBy = "studentDetail", cascade = CascadeType.ALL)
private Student student;
//Getters setters
}
This should work for you.

Question on persisting entity with Bidirectional #ManyToOne relationship using Mapstruct

This is my first time implementing #ManyToOne relationship using JPA/Mapstruct/Spring boot. I am running into the below exception: (NOTE: Using generic names as I am unable to share all the details)
java.sql.SQLIntegrityConstraintViolationException: Column 'A_ID' cannot be null for class B when I try to persist A.
Below are the relevant details. Can you help me understand what is the mistake I am making here? I have spent few hours debugging this and reading the posts without success yet.
#Mapper(componentModel="spring", uses= {BMapper.class}, collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
public interface AMapper {
#Mapping(target = "aId", source="id")
#Mapping(target = "aName", source = "name")
ADTO toDTO(final A a);
#Mapping(target = "id", ignore=true)
#Mapping(target = "name", source = "aName")
A toEntity(final ADTO aDTO);
#AfterMapping
default void setBSet(A a, #MappingTarget aDTO dto) {
for(B b : a.getBs())
b.setA(a);
}
}
#Mapper(componentModel="spring", uses= {CMapper.class}, injectionStrategy = InjectionStrategy.CONSTRUCTOR )
public interface BMapper {
#Mapping(target = "bId", source="id")
#Mapping(target = "aName", ignore=true)
BDTO toDTO(final B b);
#Mapping(target = "id", ignore=true)
#Mapping(target = "a", ignore=true)
B toEntity(final BDTO bDTO);
Set<B> bDtoToBSetEntity(Set<BDTO> set);
Set<BDTO> bSetEntityToBDto(Set<B> set);
}
Below are the class definitions of ADTO and BDTO
public class ADTO implements Serializable {
private static final long serialVersionUID = 8307772637314390585L;
private Long aId;
private String aName;
private LocalDate startDate;
private LocalDate endDate;
private Set<BDTO> bs = new HashSet<>();
// Getters / Setters here
public void addToBs(BDTO b) {
if(b != null) {
bs.add(b);
}
}
// hashCode/equals/toString methods here...
}
public class BDTO implements Serializable {
private static final long serialVersionUID = 2562084231749296452L;
private Long bId;
private String name;
private LocalDate startDate;
private LocalDate endDate;
private String aName;
// getters / setters go here..
// hashCode/equals/toString methods here...
}
Below are the class definitions of entity classes, particularly pay attention to class B where the exception is related to.
#Entity
#Table(name = "TABLEB", uniqueConstraints = {
#UniqueConstraint(columnNames = "ID")})
public class B implements Serializable {
private static final long serialVersionUID = 1407209531508355406L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID", unique = true, nullable = false)
private Long id;
#Enumerated(EnumType.STRING)
#Column(name = "NAME", nullable = false)
private String name;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "A_ID", referencedColumnName="ID")
private A a;
#Column(name = "START_DATE", unique = false, nullable = false)
private LocalDate startDate;
#Column(name = "END_DATE", unique = false, nullable = false)
private LocalDate endDate;
}
#Entity
#Table(name = "TABLEA", uniqueConstraints = {
#UniqueConstraint(columnNames = "ID")})
public class A implements Serializable {
private static final long serialVersionUID = 6926335188960198569L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID", unique = true, nullable = false)
private Long id;
#Column(name = "NAME", unique = false, nullable = false, length = 100)
private String name;
#OneToMany(mappedBy="a"/*, fetch = FetchType.EAGER*/, cascade = {CascadeType.ALL})
private Set<B> bs = new HashSet<>();
#Column(name = "START_DATE", unique = false, nullable = false)
private LocalDate startDate;
#Column(name = "END_DATE", unique = false, nullable = false)
private LocalDate endDate;
}
I am just calling save method of ADao class that persists using entity Manager.

How to get data from another table

#Entity
#Table(name="driver_duties")
public class Duties{
private String driverId;
private String hubName;
private String vehicleNumber;
// with getter and setters
}
another table
#Entity
#Table(name="driver_info")
public class Info{
private String driverId;
private String firstName;
private String lastName;
// with getter and setters
}
I want to get firstName and lastName in table driver_duties on the basis of driverId how can I get this. I am new to JPA I have tried #OnetoOne but not able to implement.
Add Duties as a data memeber in the class info
#Entity
#Table(name="driver_info")
public class Info{
private String driverId;
private String firstName;
private String lastName;
private Duties duties;
// with getter and setters
}
Ideally you need the following config, you should use an id attribute for every entity,
#Entity
#Table(name="driver_duties")
public class Duties{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private String id;
#Column(name = "hubName")
private String hubName;
#Column(name = "vehicleNumber")
private String vehicleNumber;
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "duty_id")
private Info info;
// with getter and setters
}
#Entity
#Table(name="driver_info")
public class Info{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private String id;
#Column(name = "firstName")
private String firstName;
#Column(name = "lastName")
private String lastName;
#OneToOne(mappedBy = "info", cascade = CascadeType.ALL,
fetch = FetchType.LAZY)
private Duties duties;
// with getter and setters
}

Emulating a LEFT JOIN in Spring Entity

In effect, what I am trying to do is this...
SELECT a.*, b.description, c.description FROM a
LEFT JOIN b ON b.code = a.b_code
LEFT JOIN c ON c.code = a.c_code
I would like to map this entirely using Spring/JPA framework. I've played around with #SecondaryTable only to find out that it will not work in thie case, and I've been getting a number of errors while trying to map it using #OneToOne or #JoinColumn. Here are my current entity classes...
#Entity
#Table(name = "a")
public class a {
#Id
#Column(name = "id")
private String id;
#Column(name = "b_code")
private String bCode;
//I'd like to have b.description here
#Column(name = "c_code")
private String cCode;
//I'd like to have c.description here
}
#Entity
#Table(name = "b")
public class b {
#Column(name = "code")
private String code;
#Column(name = "description")
private String description;
}
#Entity
#Table(name = "c")
public class c {
#Column(name = "code")
private String code;
#Column(name = "description")
private String description;
}
You need to use #JoinColumn with referencedColumnName as shown below.
#Entity
#Table(name = "a")
public class a {
#Id
#Column(name = "id")
private String id;
#Column(name = "b_code")
private String bCode;
//I'd like to have b.description here
#Column(name = "c_code")
private String cCode;
//I'd like to have c.description here
#OneToOne // this should be based on your joining
#JoinColumn(name = "b_code", referencedColumnName = "code", insertable = false, updatable = false)
B b;
#OneToOne// this should be based on your joining
#JoinColumn(name = "c_code", referencedColumnName = "code", insertable = false, updatable = false)
C c;
}
#Entity
#Table(name = "b")
public class B {
#Column(name = "code")
private String code;
#Column(name = "description")
private String description;
}
#Entity
#Table(name = "c")
public class C {
#Column(name = "code")
private String code;
#Column(name = "description")
private String description;
}

Customizing HATEOS URI

I have a Spring Boot Data Rest project I'm working on.
Specifically, I have the following dependencies:
dependencies {
compile 'org.springframework.boot:spring-boot-starter-data-jpa:1.1.9.RELEASE'
compile 'org.springframework.boot:spring-boot-starter-data-rest:1.1.9.RELEASE'
compile 'org.springframework.boot:spring-boot-starter-actuator:1.1.9.RELEASE'
}
I have three entities:
#Entity
#Table(name = "prefecture", uniqueConstraints={#UniqueConstraint(columnNames = {"code", "name"})})
public class Prefecture implements Serializable {
private static final long serialVersionUID = -4664664252005282494L;
#Id
#Column(name = "code")
private Integer code;
#Column(name = "name")
private String name;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "prefecture")
private List<City> cities;
...
#Entity
#Table(name = "city", uniqueConstraints = {#UniqueConstraint(columnNames = {"code", "name"})})
public class City implements Serializable {
private static final long serialVersionUID = 1077260811602686775L;
#Id
#Column(name = "code")
private Integer code;
#ManyToOne
#JoinColumn(name = "prefecture_code", referencedColumnName = "code")
private Prefecture prefecture;
#Column(name = "name", unique = true)
private String name;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "city")
private List<TownArea> townAreas;
...
#Entity
#Table(name = "town_area", uniqueConstraints={#UniqueConstraint(columnNames = {"name"})})
public class TownArea implements Serializable {
private static final long serialVersionUID = -4908446167092081914L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#Column(name = "name")
private String name;
#ManyToOne
#JoinColumn(name = "city_code", referencedColumnName = "code")
private City city;
#Column(name = "prefecture_code")
private Integer prefectureCode;
#Column(name = "postal_code")
private String postalCode;
...
And three repositories:
#RepositoryRestResource(collectionResourceRel = "cities", path = "cities")
public interface CityRepository extends PagingAndSortingRepository<City, Integer> {}
#RepositoryRestResource(collectionResourceRel = "prefectures", path = "prefectures")
public interface PrefectureRepository extends PagingAndSortingRepository<Prefecture, Integer> {}
#RepositoryRestResource(collectionResourceRel = "town_areas", path = "town_areas")
public interface TownAreaRepository extends PagingAndSortingRepository<TownArea, Integer> {}
Given this, when I run my application locally I have a set of URLs like this:
http://localhost:8080/prefectures
http://localhost:8080/prefectures/1
http://localhost:8080/prefectures/1/cities
http://localhost:8080/cities/2/townareas
http://localhost:8080/townareas/3
However, I would like to configure the following URLs:
http://localhost:8080/prefectures/1/cities/2/
http://localhost:8080/prefectures/1/cities/2/townareas
http://localhost:8080/prefectures/1/cities/2/townareas/3
Is there a way I can customize the uris to accomplish this?

Resources