Spring Data的自定义保存查询(Hibernate JPA)

时间:2017-07-31 11:09:20

标签: java sql spring hibernate spring-data-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:对象引用一个   未保存的瞬态实例 - 保存之前的瞬态实例   flushing:entity.WeeklyBoxOffice.movi​​e - &gt; entity.Movie;嵌套   异常是java.lang.IllegalStateException:   org.hibernate.TransientPropertyValueException:对象引用一个   未保存的瞬态实例 - 保存之前的瞬态实例   flushing:entity.WeeklyBoxOffice.movi​​e - &gt; entity.Movie ...引起:   org.hibernate.TransientPropertyValueException:对象引用一个   未保存的瞬态实例 - 保存之前的瞬态实例   潮红:WeeklyBoxOffice.movi​​e - &gt; entity.Movie

是否有可能以某种方式使用NativeQuery for save方法来忽略嵌套的Movie对象?

4 个答案:

答案 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