如何解决简单双向@OneToOne存储null
我尝试从文档复制中遵循@OneToOne bidrectional example,但是我在PhoneDetails phone_id列中始终使用null引用,并在获取时使用具有null详细信息的电话进行监听。
我照照文档所述创建了Phone和PhoneDetails类。
但是因为文档未指定如何测试,并且我需要开发Spring Boot应用程序,所以我创建了一个要测试的应用程序,也许在任何步骤中我都会出错。
这是我的步骤,the code I update to github希望有人可以对其进行审查
1-使用带有Java版本8的Spring工具套件在Eclipse中创建Spring Boot应用程序
2-添加依赖MySqlDriver和Spring Web
3-将pom中的依赖项添加到spring-boot-starter-data-jpa
4-在主包(com.onetoone)下为模型,控制器和存储库创建包
5-如文档中所述,在模型包中创建Phone y PhoneDetails类 包com.onetoone.models;
@Entity(name = "Phone")
public class Phone {
@Id
@GeneratedValue
private Long id;
@Column(name = "`number`")
private String number;
@OneToOne(
mappedBy = "phone",cascade = CascadeType.ALL,orphanRemoval = true,fetch = FetchType.LAZY
)
private PhoneDetails details;
//Getters and setters are omitted for brevity
public void addDetails(PhoneDetails details) {
details.setPhone( this );
this.details = details;
}
public void removeDetails() {
if ( details != null ) {
details.setPhone( null );
this.details = null;
}
}
}
@Entity(name = "PhoneDetails")
public class PhoneDetails {
@Id
@GeneratedValue
private Long id;
private String provider;
private String technology;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "phone_id")
private Phone phone;
//Getters and setters are omitted for brevity
}
在文档中,他们将此类创建为静态类,但是我必须将其删除,因为Eclipse说:“ Phone类的非法修饰符;仅允许使用public,abstract和final”。 我从javax.persistence导入了所有注释(@ Entity,@ Id ...)。
6-在其程序包中创建接口PhoneController
package com.onetoone.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.onetoone.models.Phone;
public interface PhoneRepository extends JpaRepository<Phone,Long> {
}
7-创建PhoneController
package com.onetoone.controllers;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.onetoone.models.Phone;
import com.onetoone.repository.PhoneRepository;
@RestController
@RequestMapping("/phone")
public class PhoneController {
@Autowired
PhoneRepository phoneRepository;
@PostMapping("/save")
public ResponseEntity<Boolean> savePhone(@RequestBody Phone phone) {
phoneRepository.save(phone);
return ResponseEntity.ok(true);
}
@PostMapping("/get")
public ResponseEntity<Optional<Phone>> getPhone(@RequestBody int i) {
Long id = Long.valueOf(i);
Optional<Phone> phone = phoneRepository.findById(id);
return ResponseEntity.ok(phone);
}
}
8-在文件src / main / resources下设置application.properties
spring.datasource.url= jdbc:mysql://localhost:3306/test?serverTimezone=UTC
spring.datasource.username= root
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.ddl-auto= update
我必须将?serverTimezone = UTC添加到数据库URL中,以免发生错误。
9-在我的本地数据库中创建一个名为test的模式
10-使用Spring Boot Dashboard启动应用程序,并创建表“ phone”和“ phone_details”(另一个称为“ hibernate_sequence”的表)
11-我使用邮递员将剩下的内容发送到该网址http:// localhost:8080 / phone /保存该主体
{
"number": "123-456-7890","details": {
"provider": "T-Mobile","technology": "GSM"
}
}
12-这是问题所在。它会在电话表中创建一个条目(ID,号码)
'1','123-456-7890'
和phone_details表中的其他内容(id,提供商,技术,phone_id)
'2','T-Mobile','GSM',NULL
13-当然,如果我发布帖子以http:// localhost:8080 / phone / get with body 1我会收信
{
"id": 1,"number": "123-456-7890","details": null
}
我希望任何人都可以帮助我,因为我试图将代码减少到遵循文档的最低要求,但仍然有问题:-(
@JavaMan提供的解决方案足以满足示例要求,但不适用于复杂对象。希望有人能帮助我!
解决方法
在PhoneController中,您必须添加以下行 phone.getDetails()。setPhone(phone);否则,Details对象将没有对电话的引用。
像这样
@PostMapping("/save")
public ResponseEntity<Boolean> savePhone(@RequestBody Phone phone) {
phone.getDetails().setPhone(phone);
phoneRepository.save(phone);
return ResponseEntity.ok(true);
}
此外,要使代码运行,请将@JsonIgnore
批注添加到PhoneDetails类的Phone字段中。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。