Search code examples
javaspringspring-boothibernatejdbc

Why Hibernate trying to alter my primary keys and foreign keys giving errors


Hibernate is trying to alter my primary keys but I dont want to update, can anyone help me out with what i am doing wrong.

I a trying to interact with my database to get all rows which matches a given key provided by the user and send that information back to client, upon receiving client should send a post request with another key using which i shall update the vote table and vote_count column in candidate table;

my controller

package com.onlinevoting.leadiconbackend.Controller;

import com.onlinevoting.leadiconbackend.Entity.Candidate;
import com.onlinevoting.leadiconbackend.Services.CandidateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/candidates")
public class CandidateController {

    @Autowired
    private CandidateService candidateService;

    // Endpoint to get candidates by constituency ID
    @GetMapping("/{constituencyId}")
    public List<Candidate> getCandidatesByConstituency(@PathVariable String constituencyId) {
        return candidateService.getCandidatesByConstituency(constituencyId);
    }
}


my entities
@Entity
@Table(name = "candidates")
@JsonIgnoreProperties({"constituency.state.constituencies"})
public class Candidate {
    @Id
    @Column(name="candidate_id")
    @JsonProperty("candidateId")
    private String candidateId;
    @Column(name="candidate_name")
    @JsonProperty("candidateName")
    private String candidateName;

    @Column(name="constituency_id")
    @JsonProperty("constituencyId")
    private String constituencyId;

}

@Entity
@Table(name = "constituencies")
public class Constituency {

    @Id
    @Column(name = "constituency_id")
    private String constituencyId;

    @Column(name = "constituency_name")
    private String constituencyName;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "state_id")
    private State state;
}

@Entity
@Table(name = "votes")
public class Vote {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "vote_id")
    private Long voteId;

    @Column(name = "voter_ip")
    private String voterIp;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "candidate_id")
    private Candidate candidate;

}

Error

plementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Hibernate: 
    alter table candidates
       modify column constituency_id  varchar(255)
2023-09-11T17:44:16.566+05:30  WARN 14708 --- [           main] o.h.t.s.i.ExceptionHandlerLoggedImpl     : GenerationTarget encountered exception accepting command : Error executing DDL "
    alter table candidates
       modify column constituency_id  varchar(255)" via JDBC [Cannot change column 'constituency_id': used in a foreign key constraint 'candidates_ibfk_1']

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "
    alter table candidates
       modify column constituency_id  varchar(255)" via JDBC [Cannot change column 'constituency_id': used in a foreign key constraint 'candidates_ibfk_1']
   

Solution

  • Hibernate tries to build the database as it is defined in your entity.

    try setting this environment property to validate instead: spring.jpa.hibernate.ddl-auto

    Docs: https://docs.spring.io/spring-boot/docs/1.1.0.M1/reference/html/howto-database-initialization.html

    EDIT:

    A best-practise for everyone out there. Do never use ddl-auto to update or create-drop. You should be aware of the database structure and it should be defined explicitly. You have to care that code equals the database and not the database equals the code.