При сохранении сущности, преобразованной из DTO, hibernate выбрасывает TransientPropertyValueException: объект ссылается на несохраненный временный экземпляр " - PullRequest
0 голосов
/ 19 апреля 2020

Прежде всего - я знаю, может показаться, что один и тот же вопрос задавался миллион раз. Однако это связано скорее с DTO, а не с юридическими лицами или отсутствующими каскадами. Если я сам создаю сущность и сохраняю ее, все в порядке. Проблема возникает, когда я создаю DTO, преобразую его с ModelMapper и затем пытаюсь сохранить преобразованную сущность. Если вы посмотрите на класс теста, первый тест (saveCarByEntity) проходит, а второй (saveCarByDto) выдает ошибку. Каждый связанный класс можно увидеть ниже. Заранее спасибо.

Сущности :

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

DTO-ы:

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

Тестовый класс:

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

Произошла ошибка:

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 Ответ

0 голосов
/ 19 апреля 2020

Я не знаю, что делает ваш модельный картограф, но держу пари, что если вы сохраните детали автомобиля без бампера, а затем бампера, это сработает. Может быть, вы можете заставить его работать, используя CascadeType.PERSIST в Bumper и для carDetails?

...