通过控制器持久化时如何用主键填充模型

时间:2019-10-23 08:41:36

标签: spring spring-boot spring-mvc kotlin thymeleaf

我对Spring和Thymeleaf的融合还很陌生,所以请耐心等待:

我在使用JPA模型从Thymeleaf模板获取数据时遇到了麻烦。我尝试使用顺序生成和身份生成两种策略,但它甚至不允许我加载页面

我已经尝试创建一个全新的变量,如前所述,但这显然不是问题。我知道问题可能来自html的Thymeleaf引用,但我很困惑。有没有一种方法可以自动生成ID?它甚至不允许我在表单中添加值作为ID

class Admin(@Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long, var firstName: String, var lastName: String, var login: String, var password: String) {
    @PostMapping("/addstuff")
    fun addAdmin(@ModelAttribute(name = "admin") admin: Admin, result: BindingResult, model: Model): String {
        val newAdmin: Admin = Admin(admin.id, admin.firstName, admin.lastName, admin.firstName[0].plus(admin.lastName), encoder.encode("password"))
        adminRepository.save(newAdmin)
        return "adminadd"
    }

form action="#" data-th-action="@{/addstuff}" th:object="${admin}" method="post">
    <div class="row justify-content-center" id="mainBody">
        <div class="col-8">
            <div id="student0">
                <div class="row">
                    <div class="col">
                        Administrator Information
                    </div>
                </div>
                <div class="row">
                    <div class="col">
                        <input th:field="*{firstName}" type="text" class="form-control" placeholder="First name">
                    </div>
                    <div class="col">
                        <input th:field="*{lastName}" type="text" class="form-control" placeholder="Last name">
                    </div>
                    <div class="col">
                        <input type="number" class="form-control" placeholder="Administrator ID number">
                    </div>
                </div>
                <div class="row">
                    <div class="col">
                        <label>Role
                            <div class="form-check">
                                <input class="form-check-input" type="radio" name="exampleRadios" id="adminRadio"
                                       value="option1" checked>
                                <label class="form-check-label" for="adminRadio">
                                    Administrator
                                </label>
                            </div>
                            <div class="form-check">
                                <input class="form-check-input" type="radio" name="exampleRadios" id="profRadio"
                                       value="option2">
                                <label class="form-check-label" for="profRadio">
                                    Professor
                                </label>
                            </div>
                        </label>
                    </div>
                </div>
                <hr>
            </div>
            <input id="submitAdmin" type="submit" value="Add Administrator">
            <!--            <button id="submitAdmin">Add Administrator</button>-->

        </div>
    </div>
</form>

我期望的结果应该是将数据持久保存到本地数据库中,但是我得到的错误是:

'admin' on field 'id': rejected value [null]; codes [typeMismatch.admin.id,typeMismatch.id,typeMismatch.long,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [admin.id,id]; arguments []; default message [id]]; default message [Failed to convert value of type 'null' to required type 'long'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [null] to type [@javax.persistence.Id @javax.persistence.GeneratedValue long] for value 'null'; nested exception is java.lang.IllegalArgumentException: A null value cannot be assigned to a primitive type]]

我知道它与id值有关,但是我对如何为其生成值感到困惑。如果有人感兴趣,我正在使用h2嵌入式数据库。预先感谢

2 个答案:

答案 0 :(得分:0)

尽管您的问题是数据没有在模板和JPA之间传输,但是异常清楚地说明了仅JPA的问题。在数据库中保存新的实体对象时,永远不需要传递ID。我怀疑您的数据库表中的id列未使用自动生成策略定义。您可以尝试修改它并重新运行代码吗?

答案 1 :(得分:0)

我知道了!我使用了常规的旧html名称标签,并解析了百里香并读取了它。

<div class="col">
    <input type="text" name="lastName" class="form-control" placeholder="Last name">
</div>