04_DomainClass

Code-Dateien

DateinameAktion
CODECode_Bank.zipDownload
CODECode_Pizza.zipDownload
CODECode_Urlaub.zipDownload

PDF-Dokumente

DateinameAktion
PDFFolie_Basisklasse.pdfÖffnen

Videos

DateinameAktion
VIDEOVideo_Bank_DAbspielen
VIDEOVideo_Pizza_EAbspielen
VIDEOVideo_Urlaub_DAbspielen

Lernmaterialien

JPA

It is a standard way to map Java objects to database tables and work with relational databases using objects instead of writing a lot of raw SQL.

Example idea:

  • a Java class like PizzaOrder
  • becomes a database table
  • each object becomes a row

JPA commonly uses annotations such as:

  • @Entity
  • @Id
  • @Table
  • @Column

@Entity

@Entity (jakarta.persistence.Entity)

This class should be stored in a database table.

JPA understands that:

  • This class represents a table
  • The table name is usually pizza_order (or PizzaOrder)
  • Each object = one row
  • Each field = one column
import jakarta.persistence.Entity;

@Entity
public class PizzaOrder {
    ...

Now JPA:

  • Tracks the class
  • Creates/uses a database table
  • Allows saving/loading objects
order_id order_date pizza size price quantity garlic
1 2026-04-11 Margherita Large 12.5 2 true

@Id

@Id (javax.persistence.Id).

This field is the primary key of the entity.

JPA understands that:

  • orderId uniquely identifies each record
  • It becomes the PRIMARY KEY in the database
  • No two rows can have the same orderId

JPA needs it to:

  • find an object → find(PizzaOrder.class, 1)
  • update the correct row
  • delete the correct row
import jakarta.persistence.Id;

@Entity
public class PizzaOrder {
    @Id
    private Long      orderId;
    ...

    private static final AtomicLong sequence = new AtomicLong(1000);

    public void setOrderId() {
        this.orderId = sequence.getAndIncrement();
    }
}

Optional: Auto-generated IDs

You can combine it with @GeneratedValue:

@Id
@GeneratedValue
private Long orderId;

!!! Not for NOW !!!

Properties

In JPA, we often use wrapper classes like Long, Integer, Double, and Boolean instead of primitive types like long, int, double, and boolean because wrapper classes can hold null.

  • boolean garlic → only true or false
  • Boolean garlictrue, false, or null

So Boolean can mean:

  • true = garlic requested
  • false = no garlic
  • null = not specified yet
    @Id
    private Long      orderId;
    private LocalDate orderDate;
    private String    pizza;
    private String    size;
    private Double    price;
    private Integer   quantity;
    private Boolean   garlic;

Lombok

https://projectlombok.org/api

Lombok is a Java library that reduces boilerplate code.

It can automatically generate things like:

  • getters
  • setters
  • constructors
  • toString()
  • equals() and hashCode()

So instead of writing a lot of repetitive code by hand, you add annotations.

pom.xml

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.44</version>
            <scope>provided</scope>
        </dependency>
001.png

get set toString

@Getter
@Setter
@ToString
//@NoArgsConstructor
//@AllArgsConstructor
@EqualsAndHashCode (of = "orderId", callSuper = false)
@Entity
public class PizzaOrder {

test get set toString

    @Test
    public void testGetPizza() {
        PizzaOrder o1 = new PizzaOrder();
        PizzaOrder o2 = new PizzaOrder();
        o1.setPizza("Salami");
        o2.setPizza("Pepperoni");

        assertEquals("Salami", o1.getPizza());
        assertEquals("Pepperoni", o2.getPizza());
    }

override set Method

    private static final String[] sizes = { "Small", "Medium", "Large", "Family" };

    public void setPrice(Double price) throws PizzaOrderException {
        if (price < 8)
            throw new PizzaOrderException("The min. price is 8.0 Eur");
        if (price > 30)
            throw new PizzaOrderException("The max. price is 30.0 Eur");

        this.price = price;
    }

    public void setSize(String size) throws PizzaOrderException {
        if (Arrays.asList(sizes).contains(size) == false)
            throw new PizzaOrderException("Wrong size must be: " + Arrays.toString(sizes));
        this.size = size;
    }

Constructor

    public PizzaOrder() throws PizzaOrderException {
        setOrderId();
        setOrderDate(LocalDate.now());
        setPizza("Margherita");
        setSize("Large");
        setPrice(14.0);
        setQuantity(1);
        setGarlic(true);
    }

    public PizzaOrder(LocalDate orderDate, String pizza, String size, Double price, Integer quantity, Boolean garlic) throws PizzaOrderException {
        setOrderId();
        setOrderDate (orderDate);
        setPizza (pizza);
        setSize (size);
        setPrice (price);
        setQuantity (quantity);
        setGarlic (garlic);
    }

    public PizzaOrder(Long orderId, LocalDate orderDate, String pizza, String size, Double price, Integer quantity, Boolean garlic) throws PizzaOrderException {
        setOrderId(orderId);
        setOrderDate (orderDate);
        setPizza (pizza);
        setPizza (size);
        setPrice (price);
        setQuantity (quantity);
        setGarlic (garlic);
    }

clone

The clone() method in Java is used to create a copy of an object.

Basic idea:

  • original object exists
  • clone() makes another object with the same values
public class PizzaOrder implements Cloneable {

    @Override
    public PizzaOrder clone() {
        PizzaOrder clone = new PizzaOrder(orderId, orderDate, pizza, size, price, quantity, garlic);
        return clone;
    }

Exception

public class PizzaOrderException extends RuntimeException

There is no need to add throws PizzaOrderException in the method header!!!

GIT!!!