[英]custom save query for Spring Data (Hibernate JPA)
I have two entities: 我有两个实体:
WeeklyBoxOffice.java 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 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. 现有的find方法的工作方式类似于左连接,这正是我所需要的。 But how to save WeeklyBoxOffice object without saving movie object?
但是,如何在不保存电影对象的情况下保存WeeklyBoxOffice对象呢? I don't really the idea of creating WeeklyBoxOfficeLite.
我真的不是创建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;
org.springframework.dao.InvalidDataAccessApiUsageException:org.hibernate.TransientPropertyValueException:对象引用了一个未保存的瞬态实例-在刷新之前保存该瞬态实例: 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
嵌套异常是java.lang.IllegalStateException:org.hibernate.TransientPropertyValueException:对象引用了一个未保存的瞬态实例-在刷新之前保存该瞬态实例:entity.WeeklyBoxOffice.movie-> entity.Movie ...原因:org.hibernate.TransientPropertyValueException :对象引用了一个未保存的瞬态实例-在刷新之前保存该瞬态实例:WeeklyBoxOffice.movie-> entity.Movie
Is it possible to use somehow NativeQuery for save method to ignore nested Movie object? 是否可以使用NativeQuery的save方法忽略嵌套的Movie对象?
If you removed the cascade from the association with movie
, then you should not get this error, imho... 如果您从与
movie
的关联中删除了级联,那么应该不会出现此错误,恕我直言。
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);
}
}
Why not simply set to null
the movie
field before invoking the save()
operation ? 为什么不简单地在调用
save()
操作之前将movie
field设置为null
?
In this way, Hibernate will ignore it during the flush. 这样,休眠时Hibernate将忽略它。
Use native query update something like this 使用本机查询更新类似这样的内容
public void updateSample(EntityObj entityObj) {
sql = "UPDATE Table clm SET clm.status ='"+entityObj.getStatus()+"'";
sql +=" WHERE clm.id in ("+entityObj.getId()+")";
Query q = em.createQuery(sql);
msg = q.executeUpdate();
}
OR 要么
remove CascadeType 删除CascadeType
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "name")
private Movie movie;
I think you are also sending JSON of Movie with WeeklyBoxOffice JSON like 我认为您还使用WeeklyBoxOffice JSON发送电影的JSON,例如
{
"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 因此,您必须首先创建一个MovieRepository并使用该存储库保存电影,然后使用WeeklyBoxOfficeRepository这样保存WeeklyBoxOffice
@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 其他解决方案,您可以使用
CascadeType.All
仅使用一行来保存此JSON
weeklyBoxOfficeRepository.save(weeklyBoxOffice);
this line will automatically save and will also assign movie name(id) to weeklyBoxOffice . 此行将自动保存,还将电影名称(id)分配给weeklyBoxOffice 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.