[英]custom save query for Spring Data (Hibernate JPA)
我有两个实体:
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;
}
和以下存储库:
public interface WeeklyBoxOfficeRepository extends
CrudRepository<WeeklyBoxOffice, String> {
Iterable<WeeklyBoxOffice> findByCountryOrderByWeeklyGrossDesc(String country);
}
现有的find方法的工作方式类似于左连接,这正是我所需要的。 但是,如何在不保存电影对象的情况下保存WeeklyBoxOffice对象呢? 我真的不是创建WeeklyBoxOfficeLite的想法。 现在它给出了一个例外
org.springframework.dao.InvalidDataAccessApiUsageException:org.hibernate.TransientPropertyValueException:对象引用了一个未保存的瞬态实例-在刷新之前保存该瞬态实例: 嵌套异常是java.lang.IllegalStateException:org.hibernate.TransientPropertyValueException:对象引用了一个未保存的瞬态实例-在刷新之前保存该瞬态实例:entity.WeeklyBoxOffice.movie-> entity.Movie ...原因:org.hibernate.TransientPropertyValueException :对象引用了一个未保存的瞬态实例-在刷新之前保存该瞬态实例:WeeklyBoxOffice.movie-> entity.Movie
是否可以使用NativeQuery的save方法忽略嵌套的Movie对象?
如果您从与movie
的关联中删除了级联,那么应该不会出现此错误,恕我直言。
但是无论如何,这种解决方法可能会有所帮助...
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);
}
}
为什么不简单地在调用save()
操作之前将movie
field设置为null
?
这样,休眠时Hibernate将忽略它。
使用本机查询更新类似这样的内容
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();
}
要么
删除CascadeType
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "name")
private Movie movie;
我认为您还使用WeeklyBoxOffice JSON发送电影的JSON,例如
{
"country": "xxxxxx",
"name": "xxxxxxxx",
"weeklyGross": "xxxxx",
"weeklyChange": "xxxxxx",
"movie": {
"name": "xxxxxx",
"imageLink": "xxxxx"
}
}
因此,您必须首先创建一个MovieRepository并使用该存储库保存电影,然后使用WeeklyBoxOfficeRepository这样保存WeeklyBoxOffice
@Autowired
WeeklyBoxOfficeRepository weeklyBoxOfficeRepository;
@Autowired
MovieRepository movieRepository;
public WeeklyBoxOffice saveWeeklyBoxOffice(WeeklyBoxOffice weeklyBoxOffice) {
movieRepository.save(weeklyBoxOffice.getMovie());
return weeklyBoxOfficeRepository.save(weeklyBoxOffice);
}
其他解决方案,您可以使用CascadeType.All
仅使用一行来保存此JSON
weeklyBoxOfficeRepository.save(weeklyBoxOffice);
此行将自动保存,还将电影名称(id)分配给weeklyBoxOffice 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.