Home > Blockchain >  How to map these tables with Hibernate/JPA annotations
How to map these tables with Hibernate/JPA annotations

Time:11-18

Context: it's a car repair shop.

I need to get this result when mapping my classes with Hiberante ORM:

create table appointments (
       id integer not null auto_increment,
        appointmentNumber varchar(255),
        clientName varchar(255),
        clientPhone varchar(255),
        primary key (id)
    );

    create table orders (
       id integer not null auto_increment,
        date datetime,
        appointmentNumber varchar(255),
        primary key (id)
    );

    create table parts (
       id integer not null auto_increment,
        name varchar(255),
        quantity integer,
        order_id integer,
        primary key (id)
    );

Down there, is what i tried so far, but i am new to this and not a database expert and i am a bit confused, any help to help me sort this out would be really appreciated. Thanks.

Appointment class :

@Entity
@Table(name = "appointments")
public class Appointment {
    @Id
    @Column(name = "id", nullable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Column(name = "appointmentNumber")
    private final AppointmentNumber appointmentNumber;

    @Column(name = "clientName");
    private final String clientName;

    @Column(name = "clientPhone");
    private final String clientPhone;

Order class

@Entity
@Table(name = "orders")
public class Order {
    @Id
    @Column(name = "id", nullable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Column(name = "date")
    private final LocalDateTime date;

    @OneToOne
    @JoinColumn(name = "appointmentNumber")
    private final AppointmentNumber referenceNumber;

    @OneToMany(targetEntity = Part.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private final List<Part> parts = new ArrayList<>();

Part class :

@Entity
@Table(name = "parts")
public class Part {
    @Id
    @Column(name = "id", nullable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Column(name = "name")
    private final String name;

    @Column(name = "quantity")
    private final int quantity;

    @ManyToOne
    @JoinColumn(name = "order_id", nullable=false)
    private Order order;

AppointmentNumber class ( really unsure if i need to do something with this one but i'll show the start of the class )

public class AppointmentNumber {
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private String number;

    public static AppointmentNumber create(LocalDate date, String identifier) {
        return new AppointmentNumber(date.format(FORMATTER)   "-"   identifier);
    }

    public static AppointmentNumber create(String appointmentNumberAsString) {
        return new AppointmentNumber(appointmentNumberAsString);
    }

    private AppointmentNumber(String number) {
        this.number = number;
    }

CodePudding user response:

  1. I don't understand why you have so many final variables, the only one that makes sense to me to be final is the DateTimeFormatter in AppointmentNumber
  2. The way you use AppointmentNumber in your Appointment class it should be annotated with @Embeddable and the field attribute of its type annotated with @Embedded not @Column, however the usage in the Order class hints towards AppointmentNumber being its own table, since there is no create table statement for AppointmentNumber I would suggest the same change in Order as in Appointment (embeddable AppointmentNumber). Another remark here is, what exactly is the purpose of the class AppointmentNumber, it looks to me as if it is not needed at all and could just be a field of type String in Appointment and Order, while the logic of creating an appointment number could be in some kind of service class or inside Appointment or Order
  3. I would highly recommend not to use primitive datatypes for entity field types and rather validate it to be not null in a different way
  4. fetch=FetchType.EAGER is often not a good idea as you cannot control fetching at this point anymore, it is recommended to leave fetch on lazy and fetch when needed
  • Related