在测试驱动开发中进行编程时,我偶然发现了一件奇怪的事情。即使我没有将对象更新到数据库,我的测试也不会失败。
@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()));
}
默认情况下,游戏模式设置为PLANNED
但测试成功完成,而没有调用更新方法。所以我坚信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> {
}
答案 0 :(得分:1)
我不得不说是的。我做了一个测试,但与你所做的略有不同。
我首先创建了一个normalize.css
并将类型设置为Car
,类似于您所做的:
honda
请注意,保存是在设置类型之前完成的。毫不奇怪,汽车打印出类型&#34; honda&#34;:
Car car = new Car();
carRepository.save(car);
car.setType("honda");
System.out.println("CAR="+car);
当我进行单独的提取时,在完全不同的ServiceImpl调用中,类型仍然是&#34; honda&#34;
CAR=Car:1:honda
这似乎表明汽车类型至少保存在某个地方的缓存中。但是,据我所知,我认为对象缓存是二级缓存,默认情况下不启用,我还没有完成。
不过,为了进一步检查,我添加了一种改变车法:
Car c = carRepository.findOne(id);
System.out.println("CAR="+c);
当然,在这里,汽车打印出类型=&#34;丰田&#34;,如预期的那样:
Car c = carRepository.findOne(id);
c.setType("toyota");
System.out.println("CAR="+c);
但是什么表明设置字段导致数据库更新是两件事。第一个也是最具决定性的是,退出方法后,hibernate中有一个数据库更新语句:
CAR=Car:1:toyota
其次,从后续和单独的中返回的类型:
Hibernate: update car set type=? where id=?
将类型显示为&#34;丰田&#34;:
Car c = carRepository.findOne(id);
System.out.println("CAR="+c);
答案 1 :(得分:0)
您正试图在交易结束后重复该过程 你已经实现了 试试这个
@Test
public void testStartCircleSession(){
Circle circle=Circle(defaultTheme,2,2,GameMode.ONLINE).setGameStatus(GameStatus.STARTED);
circleSessionService.createCircle(circle);
Circle circleFromRepo=circleRepository.findOne(circle.getId());
assertThat(circleFromRepo.getGameStatus(),equalTo(circle.getGameStatus()));
}