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

Issue

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(strategyGenerationType.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.urljdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_SCHEMA}?useSSLfalse&serverTimezoneUTC
spring.datasource.username${DB_USER}
spring.datasource.password${DB_PASS}

spring.jpa.properties.hibernate.dialectorg.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sqltrue
spring.jpa.properties.hibernate.format_sqltrue
logging.level.org.hibernate.SQLDEBUG
spring.jpa.hibernate.ddl-autoupdate

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.

Solution

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;
    }

Answered By – Cebrail Yilmaz

Leave a Comment