How to make one Model for similar tables? - spring

I have several similar tables in DB.
Now I use for each table own Model and Repository
But I think, this is not right decision.
Can I make a one Model and Repository for all similar tables?
#Entity
#Table(name = "BEDROOM", schema = "public")
public class BedroomModel extends AllFinishProductModel{
#Column(name = "PHOTO")
private String photo;
#Id
#Column(name = "ID")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
#Column
private String name;
#Column(name = "DESCRIPTION")
private String description;
#Column(name = "STRUCTURE") //organza, curtain ....
private String structure;
#Column(name = "PAINT") //abstraction, geometric ....
private String paint;
#Column(name = "HEIGHT")
private String height;
#Column(name = "COLOR")
private String color;
#Column(name = "QUANTITY")
private Double quantity;
#Column(name = "PRICE")
private BigDecimal price;
#Column(name = "SEWED")
private String itIsSewed;
... getters and setters
}
I have a similar tables: CABINET, GUESTROOM, CHILDREN_ROOM, KITCHEN, CURTAIN and TULLE.
Which code should be used for repository?
I tried to find answers to the questions inhttps://docs.spring.io/spring-data/data-commons/docs/1.6.1.RELEASE/reference/html/repositories.html
But I don't find answers here.
Can you give advice, how to make it or link?

You can use entity inheritance with #MappedSuperclass annotation on parent class to get common properties in child classes/tables.
So, for example you have a parent Room entity with common properties, which you annotate with #MappedSuperclass.
#MappedSuperclass
public class Room {
#Column
private String name;
#Column(name = "DESCRIPTION")
private String description;
// some more common properties
}
And concrete rooms, e.g.:
#Entity
public class Bedroom extends Room
{
// common properties will be inherited
private Bed bed;
private NightLamp nightLamp;
}
Now, the important part is that Room is not mapped as any table. The room is a "virtual" table, which doesn't exist in the db. Only concrete entities exist as tables, like Bedroom.
Here you have the link to the official javadoc:
http://docs.oracle.com/javaee/5/api/javax/persistence/MappedSuperclass.html

Related

Rest api creation for multiple path variables

I need to fetch names of all students who have enrolled for the courses.
Url:-/students/{course1}/{course2}
Eg /students/java/oracle
How to write controller, service and repository in rest api.
Entity:-
Student
Integer Id,String name and list coursenames
What about?
#Controller
#RequestMapping("/students")
public class StudentController {
#Autowired
private StudentService studentService;
// /students/java,oracle
#GetMapping(value="/{courses}")
#ResponseBody
public String getStudents(#PathVariable String[] courses) {
return studentService.getStudents(courses);
}
}
Student
#Entity
#Table(name = "student")
public class StudentDao {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#OneToMany(fetch = FetchType.EAGER)
#Fetch(value = FetchMode.SUBSELECT)
#JoinColumn(name = "id", referencedColumnName = "id")
private List<CourseDao> course;
}
Course
#Entity
#Table(name = "course")
public class CourseDao {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
}
In my opinion it is bad rest design. I'll create POST endpoint with body, which contains array with course Id's and find students by course id's.
If the parameters are optional or an array you shouldn't use a path variable but use a request parameter.

Composite primary key and ManyToOne hibernate

I'm learning Hibernate and I'm trying to make the Mapping work. My entities are as follows
Department:
#Entity
public class Department {
#Id
#GeneratedValue
private Integer id;
private String name;
private String hqLocation;
// getters and setters omitted for brevity
}
WorkerId:
#Embeddable
public class WorkerId implements Serializable {
private Integer workerId;
private Integer deptId;
// getters and setters omitted for brevity
}
Worker:
#Entity
public class Worker {
#EmbeddedId
private WorkerId id;
private String name;
private Integer age;
// How to make #ManyToOne mapping work?
private Department department;
// getters and setters omitted for brevity
}
Question: How to make #ManyToOne on the field private Department department; work? Simply adding the annotation results private Department department; as null.
I think you want to use a "derived identity"; so you should make Worker.department like this:
#Entity
public class Worker {
#EmbeddedId
private WorkerId id;
private String name;
private Integer age;
#MapsId("deptId")
#ManyToOne // <<<< edit
private Department department;
// getters and setters omitted for brevity
}
Derived identities are discussed (with examples) in the JPA 2.2 spec in section 2.4.1.
Question really is, which entity should be the owner of the relationship? would you like to map bidirectional or single way?
Here is the bidirectional example
#OneToMany(
fetch = FetchType.EAGER,
mappedBy = "department",
orphanRemoval = true,
cascade = CascadeType.ALL)
private List<Worker> workers;
#JoinColumn(name = "department_id", nullable = false)
#ManyToOne(targetEntity = Department.class, fetch = FetchType.LAZY)
private Department department;
fetch types are optional and depend on the use case

Troubles with Bidirectional One-To-One JPA

I'm coding a CRUD JPA web application. My goal is that a given parent Vehicle can only have a single child Driver, but during runtime this same Driver can instead be assigned to another Vehicle and vice versa. To my understanding, this could be accomplished via an OneToOne relationship.
I've tried some different approaches, but to no success. I can assign a Vehicle to a Driver just fine, but when I try to update/create a new Vehicle and give him a Driver, via controllers, nothing happens. I can only do it the other way around. I'm assuming this is because Vehicle is the parent and I can only create a new relation by updating a parent.
My question is, is it possible to make these updates bidirectional and how can I achieve that?
I've tried using a shared primary key, using a foreign key, using a join table. The result is always the same and I can't quite grasp why. I have an OneToMany relationship working on this application and it works as I expect it to work. I can update on one side or the other, delete on one side or the other. Both entities have been updated. OneToOne? Parent seems to have all the power.
This is what I'm working with right now:
Driver
#Entity
#Table(name= "drivers")
public class Driver {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(nullable = false)
private String name;
#Column(nullable = false)
private int age;
#OneToOne(mappedBy = "driver")
private Vehicle vehicle;
Vehicle
#Entity
#Table(name= "vehicles")
public class Vehicle {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(nullable = false)
private String make;
#Column(nullable = false)
private String model;
#Column(nullable = false)
private int mileage;
#Column(nullable = false)
private int year;
#Column(nullable = false)
private int fuel;
#OneToOne
#JoinColumn(name = "driver_id")
private Driver driver;
And just for reference, this is the OneToMany relationship I have and that I'm happy with. I'd like my OneToOne to have the same behavior, except I don't need to save a list of entities, only one.
#Entity
#Table(name="stops")
public class Stop {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(nullable = false)
private String name;
#ManyToOne
#JoinColumn(name="route_id")
private Route route;
#Entity
#Table(name="routes")
public class Route {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(nullable = false)
private String name;
#OneToMany
#JoinColumn(name = "route_id")
private List<Stop> stops = new ArrayList<>();
Any tips would be appreciated, thank you for your time.

join table and get data based on field value JPA

I have two entities
#Entity
public class Module {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
private String descr;
#OneToMany(cascade = {CascadeType.ALL})
#JoinColumn(name="ID", referencedColumnName="ID")
private List<Permissions> perms;
}
#Entity
public class Permissions {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private Integer clientId;
private String role;
private Character endorseCreate;
private Character endorseUpdate;
private Character endorseDelete;
private Character endorseView;
I am trying to fetch data by first Module.name and Permissions.clientId and Permissions.role
Something like in sql
select * from Module m, Permissions p where m.id=p.id and p.clientId=1 and p.role='ADMIN'
How can I achieve using JPA, I am using spring data aswell.
Can a method be declared in CRUD Repo provided by spring data?
I think the issue is I am unable to find way to pass values to fetch data.
Any help is greatly appreciated

Spring webFlux infinite recursion

So I'am trying Spring webFlux and have following code:
#Override
public Flux<? extends AnimalDatabaseEntity> queryAnimals() {
return async(animalsRepository.findAll().stream());
}
private <T> Flux<T> async(Stream<T> stream) {
return Flux.fromStream(stream).publishOn(scheduler);
}
The problem that I get infinite recursion, because "AnimalDatabaseEntity" has field animalFeatures.
#Entity(name = "animals")
public class AnimalDatabaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#Enumerated(EnumType.STRING)
#Column(name = "animal_type")
private AnimalType animalType;
#Column(name = "number_of_legs")
private Integer numberOfLegs;
#Column(name = "is_pet")
private boolean isPet;
#OneToMany(mappedBy = "animalDatabaseEntity", fetch = FetchType.EAGER)
private List<AnimalFeatureEntity> animalFeatures;
}
I don't really get why this does not work???
My best guess is AnimalFeatureEntity contains varaible of type AnimalDatabaseEntity which references back to List<AnimalFeatureEntity> while serializing thus causing an infinite recursion. You can prevent it by adding #JsonIgnore to AnimalDatabaseEntity if it suits your use case. However, if you wish to preserve the bidirectional relationship, then #JsonManagedReference/#JsonBackReference or #JsonIdentityInfo is the way to go.
For example usage, refer this article

Resources