我在两个对象之间有一个one-to-one
映射。
UserDO.java:
public class UserDO {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
@NotNull(message = "Username can not be null!")
private String username;
@Column(nullable = false)
@NotNull(message = "Password can not be null!")
private String password;
@Column(nullable = false)
private Boolean deleted = false;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private OnlineStatus onlineStatus;
@Column(nullable = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private ZonedDateTime dateCreated = ZonedDateTime.now();
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private CardDO card;
}
CardDO.java:
public class CardDO {
@Id
@GeneratedValue
@Column(name="id")
private Long id;
@Column(nullable = false)
private Long pan;
@Column(nullable = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
private LocalDate expirationDate;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private CardType cardType;
@Column(nullable = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private ZonedDateTime dateCreated = ZonedDateTime.now();
@OneToOne(mappedBy="card")
private UserDO user;
}
现在,当我第一次链接这两个并在repo中保存用户对象时,它工作正常,但每当我尝试更新用户对象时,它都会抛出StackOverFlow异常。
用于链接2个对象的代码:
userDO.setCard(cardDO);
userRepository.save(userDO);
更新代码:
UserDO userDO = findUser(userId);
userDO.setOnlineStatus(onlineStatus);
userRepository.save(userDO);
可能有什么不对?
答案 0 :(得分:0)
我可以通过下面的注释中的一些细微更改来运行您的代码
<强> UserDO.java 强>
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.annotation.JsonManagedReference;
@Entity
public class UserDO {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false)
@NotNull(message = "Username can not be null!")
private String username;
@Column(nullable = false)
@NotNull(message = "Password can not be null!")
private String password;
@Column(nullable = false)
private Boolean deleted = false;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private OnlineStatus onlineStatus;
@Column(nullable = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private ZonedDateTime dateCreated = ZonedDateTime.now();
@JsonManagedReference
@OneToOne(cascade = CascadeType.ALL)
private CardDO card;
}
<强> CardDO.java 强>
import java.time.LocalDate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import org.springframework.format.annotation.DateTimeFormat;
import com.fasterxml.jackson.annotation.JsonBackReference;
@Entity
public class CardDO {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false)
private Long pan;
@Column(nullable = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
private LocalDate expirationDate;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private CardType cardType;
@Column(nullable = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private ZonedDateTime dateCreated = ZonedDateTime.now();
@JsonBackReference
@OneToOne
private UserDO user;
}
如果使用以下代码保存数据userId
无法保存在cartdo
实体中
userDO.setCard(cardDO);
userRepository.save(userDO);
如果您想在userId
实体中保存cartdo
,则必须通过postman
点击您的休息API并在您的api中发送数据
{
"username":"vishal",
"password":"123456",
"onlineStatus":"OFFLINE",
"cardDO" :{
"cardType":"NEW",
"pan":"2"
}
}
我没有发送datecreated
和expirationdate
的值,因为我从我的实体中删除了这些字段,以便于查看问题。
通过邮递员存储数据后,您可以查看carddo
中的database
表,其中有一个user_id
,且该值不为空。
当您要使用findOne
CrudRepository
方法进行更新时,请先保存,然后保存如下代码。在此代码中,我还可以更新属于cardType
实体
CardDO.java
UserDO userDO = repository.findOne(userId);
CardDO card = userDO.getCard();
card.setCardType(CardType.OLD);
userDO.setOnlineStatus(OnlineStatus.ONLINE);
userDO.setCard(card);
repository.save(userDO);
答案 1 :(得分:0)
您正在获得stackoverflow异常,因为您已在@OneToOne
和UserDO
中相互声明了CardDO
映射。所以当
除了userRepository的findOne()
方法之外,它会为您提供UserDO
个对象,但此对象的@oneToOne
映射到CardDo
,因此CardDo
的对象将被提取同时从数据库。由于您的CardDo
对象与@OneToOne
进行UserDO
映射,因此同样的事情发生,即从数据库中获取UserDo
对象。这将产生无限循环并导致stackoverflow exception
。
我建议您在CardDo
实体中使用以下代码:
private Long userId;
而不是@oneToOne
映射:
@OneToOne(mappedBy="card")
private UserDO user;