java - Spring boot 创建新行而不是更新

标签 java spring spring-boot spring-data-jpa thymeleaf

这些是 bean :

@Entity
@Table(name = "bands")
public class Band implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer band_id;

@Column(name = "name")
@NotEmpty
public String name;

@Column(name = "formed")
@NotNull
public Integer formed;

@ManyToOne
@JoinColumn(name = "genre_id")
public Genre genre;

public Integer getBandId() {
    return band_id;
}

public void setBandId(Integer band_id) {
    this.band_id = band_id;
}

public String getName() {
    return this.name;
}

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

public Integer getFormed() {
    return this.formed;
}

public void setFormed(Integer formed) {
    this.formed = formed;
}

public Genre getGenre() {
    return genre;
}

public void setGenre(Genre genre) {
    this.genre = genre;
}

@XmlElement
public Genre getGenres() {
    Genre genre = getGenre();
    return genre;
}

}



@Entity
@Table(name = "genres")
@Access(AccessType.FIELD)
public class Genre implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer genre_id;

@Column(name = "name")
@NotEmpty
public String name;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "genre")
public Set<Band> bands;

public Integer getGenreId() {
    return genre_id;
}

public void setGenreId(Integer genre_id) {
    this.genre_id = genre_id;
}

public String getName() {
    return this.name;
}

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

public Set<Band> getBands() {
    return this.bands;
}

public void setBands(Set<Band> bands) {
    this.bands = bands;
}

}

这是 Controller 中初始化页面然后调用保存操作的部分:

    @RequestMapping(value = "/bands/{band_id}/edit", method = RequestMethod.GET)
public String initUpdateBandForm(@PathVariable("band_id") int band_id, ModelMap model) {
    model.addAttribute("genres", this.bandRepository.findAllGenres());
    Band band = this.bandRepository.findById(band_id);
    model.addAttribute("band", band);
    return "bands/updateBandForm";
}

@RequestMapping(value = "bands/{band_id}/edit", method = RequestMethod.POST)
public String processUpdateBandForm(@Valid @ModelAttribute("band") Band band, BindingResult result) {
    if (result.hasErrors()) {
        return "bands/updateBandForm";
    } else {
        this.bandRepository.save(band);
        return "redirect:/bands/{band_id}";
    }
}

这是存储库保存操作:

void save(Band band);

这是 updateBandForm:

<form th:object="${band}" method="post">

    <label>Name</label> 
    <input type="text" th:field="*{name}" /> 

    <label>Formed</label>
    <input type="text" th:field="*{formed}" />

    <label>Genre</label>

    <select th:field="*{genre}">
        <option th:each="genre: ${genres}" th:value="${{genre}}" th:text="${genre.name}" />
    </select>

    <br>
    <button type="submit">Update Band</button>

</form>

我还使用格式化程序:

@Service
public class GenreFormatter implements Formatter<Genre> {

@Autowired
GenreRepository genreRepository;

@Override
public String print(Genre genre, Locale locale) {
    return (genre != null ? genre.getGenreId().toString() : "");
}

@Override
public Genre parse(String text, Locale locale) throws ParseException {
    Integer id = Integer.valueOf(text);
    return this.genreRepository.findById(id);
}

}

@Configuration
@EnableWebMvc
@ComponentScan(value = {"org.springframework.samples.discography.system"})
public class WebConfig extends WebMvcConfigurerAdapter {

@Autowired
private GenreFormatter genreFormatter;

@Override
public void addFormatters(FormatterRegistry registry) {
    registry.addFormatter(genreFormatter);
}

}

Controller 方法创建一个新行而不是更新现有行...任何人都可以帮忙吗? 我错过了什么吗?

最佳答案

您的 HTML 表单没有 ID 信息。

@ModelAttribute 将创建一个 Band 对象,其中包含在 HTML 表单发送的请求参数中找到的数据。

由于您的表单只有 nameformedgenre,因此 processUpdateBandForm 中的 Band 对象 有一个未初始化的 band_id 字段,导致在保存时创建一个新的Band

在表单中添加 ID 信息来解决此问题。

<input type="hidden" th:field="*{bandId}" /> 

关于java - Spring boot 创建新行而不是更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44330265/

相关文章:

java - ejb3 toplink jpa 1.0查询和id序列策略

java - Java中基于某些约束打印字符串(字符串和数组)(压缩解压缩)

java - 配置 servlet 以使用 spring

java - 如何阻止和订阅 Flux\mono

java - 从 Response 实体获取对象的值

spring-boot - Spring-Boot 是否处理 WebFlux 上下文之外的 Kotlin 协程?

Java,如何将十进制数作为字符串转换为整数

java - Spring/Hibernate - 在 Java 中不使用 @Entity 从存储过程中获取结果

java - Spring 数据 : rollback transaction on retry

java - Web Sockets + Tomcat/Glassfish + 集群 + 负载平衡 - 有哪些选项?