我有两个实体:
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:对象引用一个 未保存的瞬态实例 - 保存之前的瞬态实例 flushing:entity.WeeklyBoxOffice.movie - &gt; entity.Movie;嵌套 异常是java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException:对象引用一个 未保存的瞬态实例 - 保存之前的瞬态实例 flushing:entity.WeeklyBoxOffice.movie - &gt; entity.Movie ...引起: org.hibernate.TransientPropertyValueException:对象引用一个 未保存的瞬态实例 - 保存之前的瞬态实例 潮红:WeeklyBoxOffice.movie - &gt; entity.Movie
是否有可能以某种方式使用NativeQuery for save方法来忽略嵌套的Movie对象?
答案 0 :(得分:1)
如果你从与movie
的关联中删除了级联,那么你不应该得到这个错误,imho ......
但无论如何也许这种解决方法可以帮助......
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);
}
}
答案 1 :(得分:0)
为什么不在调用null
操作之前简单地设置movie
save()
字段?
通过这种方式,Hibernate将在刷新期间忽略它。
答案 2 :(得分:0)
使用本地查询更新这样的
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
删除CascadeType
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "name")
private Movie movie;
答案 3 :(得分:0)
我认为你也在发送带有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 。