gpt4 book ai didi

java - 当调用 setter 时,Jpa @Repository 是否会自动更新对象?

转载 作者:行者123 更新时间:2023-12-02 03:51:25 24 4
gpt4 key购买 nike

在测试驱动开发中编程时,我偶然发现了一件奇怪的事情。即使我没有将对象更新到数据库,我的测试也不会失败。

    @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;
}
}

repo 协议(protocol)

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> {
}

最佳答案

我不得不说是的。我做了一个测试,但与你所做的略有不同。

我首先创建了一个 Car 并将类型设置为 honda,与您所做的类似:

Car car = new Car();
carRepository.save(car);
car.setType("honda");
System.out.println("CAR="+car);

请注意,保存是在设置类型之前完成的。毫不奇怪,Car 打印出“honda”类型:

CAR=Car:1:honda

当我在完全不同的 ServiceImpl 调用中进行单独的提取时,类型仍然是“honda”

Car c = carRepository.findOne(id);
System.out.println("CAR="+c);

这似乎表明该汽车类型至少保存在某处的缓存中。不过,据我所知,对象缓存(我认为是二级缓存)默认情况下并未启用,而我还没有这样做。

不过,为了进一步检查,我添加了一个换车方法:

Car c = carRepository.findOne(id);
c.setType("toyota");
System.out.println("CAR="+c);

当然,汽车按照预期打印为 type =“Toyota”:

CAR=Car:1:toyota

但是,表明设置字段已导致数据库更新的原因有两件事。第一个,也是最决定性的,是在我退出该方法后,hibernate 有一个数据库更新语句:

Hibernate: update car set type=? where id=?

其次,从后续的单独查找返回的类型:

Car c = carRepository.findOne(id);
System.out.println("CAR="+c);

将类型显示为“Toyota”:

CAR=Car:1:toyota

关于java - 当调用 setter 时,Jpa @Repository 是否会自动更新对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35845407/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com