org.hibernate.PersistentObjectException:传递给persist的分离实体

时间:2015-08-11 07:01:45

标签: java hibernate spring-data spring-data-jpa

我编写第一个java应用程序来读取rss流并使用springspring-datahibernate。 我的模特。 RssFeed

@Entity(name = "RssFeed")
@Table(name = "FEED")
@JsonIgnoreProperties({"rssChannel"})
public class RssFeed {

  @Id
  @GeneratedValue
  @Column
  private Integer id;

  @Column(unique = true)
  @Index(name = "title_index")
  private String title;

  @Column
  @URL
  private String link;

  @Column
  private String description;

  @Column
  private String content;

  @Column
  @Temporal(TemporalType.TIMESTAMP)
  private Date pubDate;

  @Column
  @Temporal(TemporalType.TIMESTAMP)
  private Date updateDate;


  @ManyToOne
  @JoinColumn(name = "channelId")
  private RssChannel rssChannel;

  @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
  @JoinTable(name = "feed_category",
          joinColumns = {@JoinColumn(name = "feed_id", nullable = false, updatable = false)},
          inverseJoinColumns  = {@JoinColumn(name = "category_id", nullable = false, updatable = false)})
  private Set<RssCategory> rssCategories = new LinkedHashSet<RssCategory>();
}

RssChannel

@Entity(name = "RssChannel")
@Table(name = "Channel",
        uniqueConstraints = @UniqueConstraint(columnNames = {"link"}))
@JsonIgnoreProperties({"feeds"})
public class RssChannel implements Serializable{

  @Id
  @GeneratedValue
  @Column
  private Integer id;

  @Column
  private String title;

  @Column(unique = true)
  @org.hibernate.validator.constraints.URL
  private String link;

  @Column
  @org.hibernate.validator.constraints.URL
  private String image;

  @Column
  private String description;

  @OneToMany(mappedBy = "rssChannel", cascade = CascadeType.ALL, orphanRemoval = true)
  private List<RssFeed> feeds = new LinkedList<RssFeed>();
}

RssCategory

@Entity(name = "RssCategory")
@Table(name = "CATEGORY")
@JsonIgnoreProperties({"rssFeeds"})
public class RssCategory {

    @Id
    @GeneratedValue
    @Column
    private Integer id;

    @Column(unique = true)
    private String title;

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "rssCategories")
    public Set<RssFeed> rssFeeds = new LinkedHashSet<RssFeed>();
}

我使用CrudRepository来处理数据。当保存RssFeed没有多少时,它就可以了:

RssChannel channel = rssChannelService.get(url.toString());
rssFeed.setRssChannel(channel);
rssFeedService.save(rssFeed);

但是当我添加RssCategory时:

rssCategory rssCategory = rssCategoryService.findOrCreate("test");
rssFeed.getRssCategories().add(rssCategory);
rssFeedService.save(rssFeed);

获得例外:rg.hibernate.PersistentObjectException: detached entity passed to persist: RssCategory

我的RssFeedServiceImpl:

@Service
public class RssFeedServiceImpl implements RssFeedService {

  @Autowired
  private RssChannelDAO rssChannelDAO;

  @Autowired
  private RssFeedDAO rssFeedDAO;

  @Override
  public Page<RssFeed> findAll(Pageable pageable) {
    return rssFeedDAO.findAll(pageable);
  }

  @Override
  public Page<RssFeed> findAll(int rssChannelId, Pageable pageable) {
    RssChannel rssChannel = rssChannelDAO.findOne(rssChannelId);
    return rssFeedDAO.findByRssChannel(rssChannel, pageable);
  }

  @Override
  public RssFeed get(String title) {
    return rssFeedDAO.findByTitle(title);
  }

  @Override
  public RssFeed save(RssFeed rssFeed) {
    return rssFeedDAO.save(rssFeed);
  }

}

和RssCategoryServiceImpl:

@Service
public class RssCategoryServiceImpl implements RssCategoryService {

    @Autowired
    RssCategoryDAO rssCategoryDAO;

    @Override
    public RssCategory findOrCreate(String title) {
        RssCategory category = rssCategoryDAO.findByTitle(title);
        if (category == null) {
            category = new RssCategory();
            category.setTitle(title);
            category = rssCategoryDAO.save(category);
        }
        return category;
    }
}

如何节省多少?

1 个答案:

答案 0 :(得分:0)

您可能需要先保存RssCategory,以便在feed_category表中存储ID。进行作业时,将自动进行最后一次保存:

rssFeed.getRssCategories().add(rssCategory); 

但首先你需要这样做:

rssFeedService.save(rssCategory);

您可能需要将此操作置于事务中。