When saving entity converted from a DTO, hibernate throws TransientPropertyValueException: object references an unsaved transient instance"

我与影子孤独终老i 提交于 2020-06-17 10:24:43

问题


First off - I know, it might seem like the same question has been asked a million times. However, this is related rather to DTOs, not entities nor missing cascades. If I create an entity myself and save it, everything is fine. The problem occurs when I create a DTO, convert it with ModelMapper and then try to save the converted entity. If you look at the test class, the first test(saveCarByEntity) passes but the second(saveCarByDto) one produces the error. Every class connected can be seen below. Thank you in advance.

The entities:

@Data
@Entity
public class Car {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne(mappedBy = "car", cascade = CascadeType.PERSIST)
    private CarDetails carDetails;
}
@Data
@Entity
public class CarDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne(mappedBy = "carDetails", cascade = CascadeType.PERSIST)
    private Bumper bumper;

    @OneToOne
    private Car car;
}
@Data
@Entity
public class Bumper {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne
    private CarDetails carDetails;
}

The DTO-s:

@Data
public class CarDto {
    private Long id;
    private CarDetailsDto carDetails;
}
@Data
public class CarDetailsDto {
    private Long id;
    private BumperDto bumper;
    private CarDto car;
}
@Data
public class BumperDto {
    private Long id;
    private CarDetailsDto carDetails;
}

The test class:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
class CarTests {
    @Autowired
    private ModelMapper modelMapper;

    @Autowired
    private CarRepository carRepository;

    @BeforeEach
    public void setup() {
    }

    @Test
    public void saveCarByEntity() {
        Car car = new Car();
        CarDetails carDetails = new CarDetails();
        Bumper bumper = new Bumper();

        car.setCarDetails(carDetails);
        carDetails.setCar(car);
        carDetails.setBumper(bumper);
        bumper.setCarDetails(carDetails);

        Car savedEntity = carRepository.save(car);
    }

    @Test
    public void saveCarByDto() {
        CarDto carDto = new CarDto();
        CarDetailsDto carDetails = new CarDetailsDto();
        BumperDto bumper = new BumperDto();

        carDto.setCarDetails(carDetails);
        carDetails.setCar(carDto);
        carDetails.setBumper(bumper);
        bumper.setCarDetails(carDetails);

        Car car = modelMapper.map(carDto, Car.class);

        Car savedEntity = carRepository.save(car);
    }
}

Error produced:

nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.somepackage.model.Bumper.carDetails -> com.somepackage.model.CarDetails

CarRepository:

@Repository
public interface CarRepostiory extends JpaRepository<Car, Long> {
}

回答1:


I don't know what your model mapper does, but I bet if you persist car details without the bumper and then the bumper, it will work. Maybe you can make it work by using CascadeType.PERSIST in the Bumper for carDetails as well?



来源:https://stackoverflow.com/questions/61301600/when-saving-entity-converted-from-a-dto-hibernate-throws-transientpropertyvalue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!