Home > Blockchain >  Spring Boot: How to make entity reflect database column changes?
Spring Boot: How to make entity reflect database column changes?

Time:11-20

I am using spring boot as a backend rest API and connecting to a MySQL database. I created the initial entity and database table that it would map to. I realized one of the columns in my database was named incorrectly and updated its name in the database and updated my entity to reflect the change as well. After doing so, when I send a GET or POST request to my controller endpoints, the values of the returned object do not reflect the changes I made to the entity/database. I have tried changing the spring.jpa.hibernate.ddl-auto property in my applications.properties file to update, create, and create drop, none of which had any success. Here is my entity class, applications.properties file, my controller endpoints, my repository, and 2 images, one of my database table and one of the response from the GET endpoint.

Skin.java

import java.math.BigDecimal;
import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;

@Entity
@Table(name="skins")
@JsonIdentityInfo(
          generator = ObjectIdGenerators.PropertyGenerator.class, 
          property = "id")
public class Skin {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private Long id;
    
    @Column(name="category")
    private String category;
    
    @Column(name="collection")
    private String collection;
    
    @Column(name="quality")
    private String quality;
    
    @Column(name="wear")
    private String wear;    

    @Column(name="weapon")
    private String weapon;
    
    @Column(name="name")
    private String name;
    
    @Column(name="price")
    private BigDecimal price;
    
    @Column(name="quantity")
    private int quantity;
    
    @Column(name="date_bought")
    private Date dateBought;
    
    @ManyToOne(cascade= {CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH})
    @JoinColumn(name="trade_id")
    private Trade trade;
    
    @Column(name="outcome_sell_price")
    private BigDecimal outcomeSellPrice;
    
    @Column(name="date_traded")
    private Date dateTraded;
    
    @Column(name="sell_price")
    private BigDecimal sellPrice;
    
    @Column(name="date_sold")
    private Date dateSold;
    
    public Skin() {
        
    }

    public Skin(String category, String collection, String quality, String wear, String weapon, String name,
            BigDecimal price, int quantity, Date dateBought, Trade trade, BigDecimal outcomeSellPrice, Date dateTraded,
            BigDecimal sellPrice, Date dateSold) {
        this.category = category;
        this.collection = collection;
        this.quality = quality;
        this.wear = wear;
        this.weapon = weapon;
        this.name = name;
        this.price = price;
        this.quantity = quantity;
        this.dateBought = dateBought;
        this.trade = trade;
        this.outcomeSellPrice = outcomeSellPrice;
        this.dateTraded = dateTraded;
        this.sellPrice = sellPrice;
        this.dateSold = dateSold;
    }

    public String getWeapon() {
        return weapon;
    }

    public void setWeapon(String weapon) {
        this.weapon = weapon;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getCollection() {
        return collection;
    }

    public void setCollection(String collection) {
        this.collection = collection;
    }

    public String getWear() {
        return wear;
    }

    public void setWear(String wear) {
        this.wear = wear;
    }

    public String getQuality() {
        return quality;
    }

    public void setQuality(String quality) {
        this.quality = quality;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public Date getDateBought() {
        return dateBought;
    }

    public void setDateBought(Date dateBought) {
        this.dateBought = dateBought;
    }

    public Trade getTrade() {
        return trade;
    }

    public void setTrade(Trade trade) {
        this.trade = trade;
    }

    public BigDecimal getSellPrice() {
        return sellPrice;
    }

    public void setSellPrice(BigDecimal sellPrice) {
        this.sellPrice = sellPrice;
    }

    public Date getDateTraded() {
        return dateTraded;
    }

    public void setDateTraded(Date dateTraded) {
        this.dateTraded = dateTraded;
    }

    public BigDecimal getSoldAt() {
        return outcomeSellPrice;
    }

    public void setSoldAt(BigDecimal soldAt) {
        this.outcomeSellPrice = soldAt;
    }


    public Date getDateSold() {
        return dateSold;
    }

    public void setDateSold(Date dateSold) {
        this.dateSold = dateSold;
    }

    @Override
    public String toString() {
        return "Skin [id="   id   ", category="   category   ", collection="   collection   ", quality="   quality
                  ", wear="   wear   ", weapon="   weapon   ", name="   name   ", price="   price   ", quantity="
                  quantity   ", dateBought="   dateBought   ", trade="   trade   ", outcomeSellPrice="   outcomeSellPrice
                  ", dateTraded="   dateTraded   ", sellPrice="   sellPrice   ", dateSold="   dateSold   "]";
    }
}

Controller Endpoints

@Autowired
SkinRepository sr;

@GetMapping("")
public List<Skin> getSkins() {
    return sr.findByTradeIdNullAndDateSoldNull();
}

@PostMapping("")
public Skin insertSkin(@RequestBody Skin skin) {
    // need to figure out why this isn't picking up the database changes
    return sr.save(skin);
}   

SkinRepository.java

@Repository
public interface SkinRepository extends JpaRepository<Skin, Long> {
        
    List<Skin> findByTradeIdNullAndDateSoldNull();
}

application.properties

spring.datasource.url=jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_SCHEMA}?useSSL=false&serverTimezone=UTC
spring.datasource.username=${DB_USER}
spring.datasource.password=${DB_PASS}

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
spring.jpa.hibernate.ddl-auto=update

Database Table

This is the response I get when sending a request to the GET endpoint. The value soldAt is the old name of the column before changing it, it should be outcome_sell_price.

GET endpoint response

Any thoughts on how I can get the response from the endpoints to match the database and entity would be greatly appreciated. Thanks in advance.

CodePudding user response:

Some of the accessor and mutator is unusable in your code so remove it because it produce error while compile your code and set hibernate.ddl-auto to create it can create a new table in your database otherwise use create it can drop your database and create table based on entity.

New Skin Entity

@Entity
@Table(name="skins")
@JsonIdentityInfo(
          generator = ObjectIdGenerators.PropertyGenerator.class, 
          property = "id")
public class Skin {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private Long id;
    
    @Column(name="category")
    private String category;
    
    @Column(name="collection")
    private String collection;
    
    @Column(name="quality")
    private String quality;
    
    @Column(name="wear")
    private String wear;    

    @Column(name="weapon")
    private String weapon;
    
    @Column(name="name")
    private String name;
    
    @Column(name="price")
    private BigDecimal price;
    
    @Column(name="quantity")
    private int quantity;
    
    @Column(name="date_bought")
    private Date dateBought;
    
    @ManyToOne(cascade= {CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH})
    @JoinColumn(name="trade_id")
    private Trade trade;
    
    @Column(name="outcome_sell_price")
    private BigDecimal outcomeSellPrice;
    
    @Column(name="date_traded")
    private Date dateTraded;
    
    @Column(name="sell_price")
    private BigDecimal sellPrice;
    
    @Column(name="date_sold")
    private Date dateSold;

    public Skin(Long id, String category, String collection, String quality, String wear, String weapon, String name,
            BigDecimal price, int quantity, Date dateBought, Trade trade, BigDecimal outcomeSellPrice, Date dateTraded,
            BigDecimal sellPrice, Date dateSold) {
        this.id = id;
        this.category = category;
        this.collection = collection;
        this.quality = quality;
        this.wear = wear;
        this.weapon = weapon;
        this.name = name;
        this.price = price;
        this.quantity = quantity;
        this.dateBought = dateBought;
        this.trade = trade;
        this.outcomeSellPrice = outcomeSellPrice;
        this.dateTraded = dateTraded;
        this.sellPrice = sellPrice;
        this.dateSold = dateSold;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getCollection() {
        return collection;
    }

    public void setCollection(String collection) {
        this.collection = collection;
    }

    public String getQuality() {
        return quality;
    }

    public void setQuality(String quality) {
        this.quality = quality;
    }

    public String getWear() {
        return wear;
    }

    public void setWear(String wear) {
        this.wear = wear;
    }

    public String getWeapon() {
        return weapon;
    }

    public void setWeapon(String weapon) {
        this.weapon = weapon;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public Date getDateBought() {
        return dateBought;
    }

    public void setDateBought(Date dateBought) {
        this.dateBought = dateBought;
    }

    public Trade getTrade() {
        return trade;
    }

    public void setTrade(Trade trade) {
        this.trade = trade;
    }

    public BigDecimal getOutcomeSellPrice() {
        return outcomeSellPrice;
    }

    public void setOutcomeSellPrice(BigDecimal outcomeSellPrice) {
        this.outcomeSellPrice = outcomeSellPrice;
    }

    public Date getDateTraded() {
        return dateTraded;
    }

    public void setDateTraded(Date dateTraded) {
        this.dateTraded = dateTraded;
    }

    public BigDecimal getSellPrice() {
        return sellPrice;
    }

    public void setSellPrice(BigDecimal sellPrice) {
        this.sellPrice = sellPrice;
    }

    public Date getDateSold() {
        return dateSold;
    }

    public void setDateSold(Date dateSold) {
        this.dateSold = dateSold;
    }

Change in application.properties

spring.jpa.hibernate.ddl-auto= create

OR

spring.jpa.hibernate.ddl-auto= create-drop

CodePudding user response:

The reason why you still get soldAt related names might be because you have the following getter and setters. Remove or update this getter and setters too and see if you still get erroneous responses.

    public BigDecimal getSoldAt() {
        return outcomeSellPrice;
    }

    public void setSoldAt(BigDecimal soldAt) {
        this.outcomeSellPrice = soldAt;
    }
  • Related