java调用setter时,Jpa@Repository会自动更新对象吗?
在测试驱动开发中编程时,我偶然发现了一件奇怪的事情。即使我没有将对象更新到数据库,我的测试也不会失败
@Test
public void testStartCircleSession(){
Circle circle=circleSessionService.createCircle(defaultTheme,2,2,GameMode.ONLINE);
circle.setGameStatus(GameStatus.STARTED);
//circleSessionService.updateCircle(defaultCircle); --> this calls the update method
Circle circleFromRepo=circleRepository.findOne(circle.getId());
assertThat(circleFromRepo.getGameStatus(),equalTo(circle.getGameStatus()));
}
默认情况下,gamemode设置为PLANNED
,但是测试在没有调用update方法的情况下成功完成。所以我坚信Jpa会在调用setter时更新对象,但我不确定
圆DOM
package be.kdg.kandoe.backend.dom;
import be.kdg.kandoe.backend.dom.participations.CircleParticipation;
import be.kdg.kandoe.backend.dom.roles.Role;
import javafx.beans.DefaultProperty;
import org.springframework.hateoas.Identifiable;
import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "Circle")
public class Circle implements Serializable, Identifiable<Integer>{
@Id
@GeneratedValue
@Column(name = "CircleId", nullable = false)
private Integer circleId;
@OneToMany(targetEntity = CircleParticipation.class,cascade = CascadeType.ALL,fetch = FetchType.EAGER,mappedBy = "circle")
private List<CircleParticipation> circleParticipations;
@OneToMany(targetEntity = Card.class,cascade = CascadeType.ALL,fetch = FetchType.EAGER,mappedBy = "circle")
private List<Card> cards;
@OneToMany(targetEntity = Vote.class,cascade = CascadeType.ALL,fetch = FetchType.EAGER,mappedBy = "circle")
private List<Vote> votes;
@OneToOne(targetEntity = Theme.class, cascade = CascadeType.ALL,fetch = FetchType.EAGER)
@JoinColumn(name="ThemeId",nullable = false)
private Theme theme;
@Column(name = "GameMode", nullable = false)
@Enumerated(EnumType.STRING)
private GameMode gameMode;
@Column(name = "GameStatus", nullable = false)//,columnDefinition ="PLANNED")
@Enumerated(EnumType.STRING)
private GameStatus gameStatus;
@Column(name = "TurnTime", nullable = false)
private Integer turnTime;
@Column(name = "TotalRounds", nullable = false)
private Integer totalRounds;
@OneToOne(targetEntity = CircleParticipation.class, cascade = CascadeType.ALL,fetch = FetchType.EAGER)
@JoinColumn(name="CurrentCircleParticipationId") //current user
private CircleParticipation currentCircleParticipation;
@Column(name = "CurrentRound", nullable = false)
private Integer currentRound;
public CircleParticipation getCurrentCircleParticipation() {
return currentCircleParticipation;
}
public void setCurrentCircleParticipation(CircleParticipation currentCircleParticipation) {
this.currentCircleParticipation = currentCircleParticipation;
}
public GameMode getGameMode() {
return gameMode;
}
public Integer getTurnTime() {
return turnTime;
}
public Integer getTotalRounds() {
return totalRounds;
}
public Circle(Theme theme, int turnTime, int totalRounds, GameMode mode){
this.theme = theme;
this.turnTime = turnTime;
this.totalRounds = totalRounds;
this.gameMode = mode;
this.currentRound=1;
circleParticipations = new ArrayList<>();
gameStatus=GameStatus.PLANNED;
}
public Circle() {
circleParticipations = new ArrayList<>();
}
public Integer getCircleId() {
return circleId;
}
public List<Vote> getVotes() {
return votes;
}
public List<Card> getCards() {
return cards;
}
public Theme getTheme() {
return theme;
}
@Override
public Integer getId() {
return circleId;
}
public List<CircleParticipation> getCircleParticipations() {
return circleParticipations;
}
public Integer getCurrentRound() {
return currentRound;
}
public void setCurrentRound(int currentRound) {
this.currentRound = currentRound;
}
public CircleParticipation getCreatorParticipation() {
return this.circleParticipations.stream().filter(p->p.getRoles().contains(Role.toRole(Role.RoleType.CREATOR))).findFirst().get();
}
public GameStatus getGameStatus() {
return gameStatus;
}
public void setGameStatus(GameStatus gameStatus) {
this.gameStatus = gameStatus;
}
}
回购
package be.kdg.kandoe.backend.persistence.api;
import be.kdg.kandoe.backend.dom.Circle;
import be.kdg.kandoe.backend.dom.Theme;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* Created by claudiu on 23/02/16.
*/
public interface CircleRepository extends JpaRepository<Circle,Integer>, JpaSpecificationExecutor<Circle> {
}
# 1 楼答案
我不得不说是的。我做了一个测试,但和你做的略有不同
我首先创建了一个
Car
,并将类型设置为honda
,类似于您所做的:请注意,保存是在设置类型之前完成的。毫不奇怪,汽车打印为“honda”型:
当我在一个完全不同的ServiceImpl调用中单独提取时,类型仍然是“honda”
这似乎表明汽车类型至少保存在某个缓存中。但是,我知道对象缓存(我认为是二级缓存)在默认情况下是不启用的,我还没有启用
不过,为了进一步检查,我添加了一个change car方法:
当然,在这里,汽车打印为type=“Toyota”,正如预期的那样:
但是,有两件事表明设置字段导致了数据库中的更新。首先,也是最具决定性的一点是,在我退出该方法后,hibernate中有一条数据库更新语句:
其次,还有从后续和单独的查找返回的类型:
将类型显示为“Toyota”:
# 2 楼答案
您正在尝试在事务结束后重复该过程 你所取得的成就 试试这个