Reputation:
I have two entities:
WeeklyBoxOffice.java
@Entity
public class WeeklyBoxOffice {
@NotNull
private String country;
@Id
@NotNull
private String name;
@NotNull
private long weeklyGross;
@NotNull
private double weeklyChange;
@OneToOne//(fetch = FetchType.LAZY, cascade=CascadeType.ALL )
@JoinColumn(name = "name")
private Movie movie;
}
Movie.java
@Entity
@Table(name = "movies")
public class Movie {
@Id
@NotNull
private String name;
@NotNull
private String imageLink;
}
And following repository:
public interface WeeklyBoxOfficeRepository extends
CrudRepository<WeeklyBoxOffice, String> {
Iterable<WeeklyBoxOffice> findByCountryOrderByWeeklyGrossDesc(String country);
}
Existing find method works like left join, which is exactly what I need. But how to save WeeklyBoxOffice object without saving movie object? I don't really the idea of creating WeeklyBoxOfficeLite. Now it gives an exception
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : entity.WeeklyBoxOffice.movie -> entity.Movie; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : entity.WeeklyBoxOffice.movie -> entity.Movie ... Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : WeeklyBoxOffice.movie -> entity.Movie
Is it possible to use somehow NativeQuery for save method to ignore nested Movie object?
Upvotes: 0
Views: 7659
Reputation: 30379
If you removed the cascade from the association with movie
, then you should not get this error, imho...
But anyway maybe this workaround can help...
public class WeeklyBoxOfficeService {
@Autoware
private WeeklyBoxOfficeRepo repo;
public WeeklyBoxOffice saveWithoutMovie(WeeklyBoxOffice weeklyBoxOffice) {
weeklyBoxOffice.setMovie(null); // 'unlink' movie from BO
repo.save(weeklyBoxOffice); // save BO without movie
}
}
@RestController
@RequestMapping("/weeklyBoxOffice")
public class WeeklyBoxOfficeController {
@Autoware
private WeeklyBoxOfficeService service;
@PostMapping
public ResponseEntity<?> saveWithoutMovie(@RequestBody WeeklyBoxOffice weeklyBoxOffice) {
WeeklyBoxOffice result = service.saveWithoutMovie(weeklyBoxOffice);
return ResponseEntity.ok(result);
}
}
Upvotes: 1
Reputation: 376
I think you are also sending JSON of Movie with WeeklyBoxOffice JSON like
{
"country": "xxxxxx",
"name": "xxxxxxxx",
"weeklyGross": "xxxxx",
"weeklyChange": "xxxxxx",
"movie": {
"name": "xxxxxx",
"imageLink": "xxxxx"
}
}
So you have to first create a MovieRepository and save movie using this repository and then save WeeklyBoxOffice using WeeklyBoxOfficeRepository like this
@Autowired
WeeklyBoxOfficeRepository weeklyBoxOfficeRepository;
@Autowired
MovieRepository movieRepository;
public WeeklyBoxOffice saveWeeklyBoxOffice(WeeklyBoxOffice weeklyBoxOffice) {
movieRepository.save(weeklyBoxOffice.getMovie());
return weeklyBoxOfficeRepository.save(weeklyBoxOffice);
}
Other solution, you can use CascadeType.All
for saving this JSON using only one line
weeklyBoxOfficeRepository.save(weeklyBoxOffice);
this line will automatically save and will also assign movie name(id) to weeklyBoxOffice.
Upvotes: 0
Reputation: 131436
Why not simply set to null
the movie
field before invoking the save()
operation ?
In this way, Hibernate will ignore it during the flush.
Upvotes: 0