当调用setter时,Jpa @Repository会自动更新对象吗?

时间:2016-03-07 13:45:53

标签: java jpa repository setter

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

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

2 个答案:

答案 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()));
    }