When configuring relational mapping in 3.2, the table names are different from those in 3.1.

Posted by axiom82 on Mon, 06 May 2019 04:50:03 +0200

Chapter 3.2 describes the mapping relationship of the corresponding classes according to the steps in the book. It is found that at startup, all the tables previously built in Chapter 3.1 were deleted and re-established, and the data of Ingredient table was lost. Because of the use of JPA, hibernate was used by default, all tables were deleted and table structures were re-established at startup, and the statements in schema.sql and data.sql were not executed. The solution is simple. Add the following configuration to the application.properties file:

spring.jpa.hibernate.ddl-auto=none

Turn off the ddl processing function of hibernate.

However, there are still some areas that need to be adjusted. The table fields in Chapter 3.1 are named in the java style. When executing hibernate queries, errors will be reported. Take Taco for example:

package tacos;
import java.util.Date;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.PrePersist;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import lombok.Data;

@Data
@Entity
public class Taco {
  
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private Long id;
  
  private Date createdAt;
  
  @NotNull
  @Size(min=5, message="Name must be at least 5 characters long")

  private String name;

  @ManyToMany(targetEntity=Ingredient.class)
  @Size(min=1, message="You must choose at least 1 ingredient")
  private List<Ingredient> ingredients;
  
  @PrePersist
  void createdAt() {
    this.createdAt = new Date();
  }
  
}

Since the createdAt attribute is not annotated with the @Column annotation, you would think that its corresponding field would be createdAt. In fact, when you query it again, you will find that the field he mapped is created_at. Even if you add @Column (name= "createdAt") to it, it doesn't work, but you can add @Column (name= "createdat") to it. It may be that spring forces your fields to conform to sql's field naming criteria, automatically converting familiar java hump naming names into underscored forms.

If it's too cumbersome to deal with it step by step in the way of @Column(name="createdat"), the ddl statement of the table structure is modified directly as follows:

drop table Taco_Ingredients if exists;
drop table Taco_Order_Tacos if exists;

create table if not exists Ingredient (
  id varchar(4) not null,
  name varchar(25) not null,
  type varchar(10) not null
);

create table if not exists Taco (
  id identity,
  name varchar(50) not null,
  created_at timestamp not null
);

create table if not exists Taco_Ingredients (
  taco_id bigint not null,
  ingredients_id varchar(4) not null
);

alter table Taco_Ingredients
    add foreign key (taco_id) references Taco(id);
alter table Taco_Ingredients
    add foreign key (ingredients_id) references Ingredient(id);

create table if not exists Taco_Order (
    id identity,
    delivery_name varchar(50) not null,
    delivery_street varchar(50) not null,
    delivery_city varchar(50) not null,
    delivery_state varchar(2) not null,
    delivery_zip varchar(10) not null,
    cc_number varchar(16) not null,
    cc_expiration varchar(5) not null,
    ccCVV varchar(3) not null,
    placed_at timestamp not null
);

create table if not exists Taco_Order_Tacos (
    order_id bigint not null,
    taco_id bigint not null
);

alter table Taco_Order_Tacos
    add foreign key (order_id) references Taco_Order(id);
alter table Taco_Order_Tacos
    add foreign key (taco_id) references Taco(id);

Put the above statement into schema.sql file to solve the problem perfectly.

Topics: Java Hibernate SQL Spring