Java,Hibernate - 在使用单独的嵌入式密钥类持久保存实体后无法检索id

时间:2017-07-07 21:45:17

标签: spring hibernate jpa spring-boot

我正在研究一个示例Springboot服务器应用程序并使用hibernate for JPA。我正在使用通用存储库模式,在我的实体上执行所有CRUD操作。我跟着这个例子:  我遇到的http://www.concretepage.com/spring-boot/spring-boot-rest-jpa-hibernate-mysql-example。 (我的想法是拥有一个通用存储库是为所有CRUD操作提供类似的实现,而不是在每个服务/ DAO或每个实体的存储库实现中明确说明一个)在上面的例子中,@ ID属性与实体。因此,我能够持久化实体,并且在 entityManager.persist(object)

之后,id将反映在对象中

在我的代码中,我将Key类分开,并在Entity类中引用它。在EntityManager上调用persist时,会在数据库中创建一行(因为主键的列设置为在数据库中自动递增),但在调用persist()之后,该对象中不会反映相同的ID。在任何时候,密钥类中的ID属性都设置为0,这是默认的int值。我想知道是否有一种方法可以通过Session或EntityManager获取插入对象的ID。如果没有在Entity类本身中包含主键,还有任何替代策略来解决此问题。 (截至目前,我已经查看了SO上的多个帖子,但未能找到我问题的解决方案。)

实体类

@Entity
@Table(name = "articles")
public class SampleArticle extends AbstractDomainObject {
/** The serialVersionUID. */
private static final long serialVersionUID = 7072648542528280535L;
/** Uniquely identifies the article. */
@EmbeddedId
@AttributeOverride(name = "articleId", column = @Column(name = "article_id"))
@GeneratedValue(strategy = GenerationType.IDENTITY)
//@GeneratedValue(strategy = GenerationType.AUTO)
private SampleArticleKey key;
/** Indicates the title. */
@Column(name = "title")
private String title;

关键班

@Embeddable
public class SampleArticleKey extends AbstractDomainKey {
/**
 * Serial version id.
 */
private static final long serialVersionUID = 1325990987094850016L;
/** The article id. */
private int articleId;

存储库类

@Repository
@Transactional
public class SampleArticleRepository extends 
AbstractRepository<SampleArticle, SampleArticleKey> implements 
ISampleArticleRepository<SampleArticle, SampleArticleKey> {
/*
 * (non-Javadoc)
 * @see
 * com.wpi.server.entity.repository.ISampleArticleRepository#addArticle
 * (java.lang.Object)
 */
@Override
public SampleArticle create(SampleArticle article) throws Exception {
    return super.create(article);
}

抽象存储库

@Transactional
public abstract class AbstractRepository<T extends AbstractDomainObject, K 
extends AbstractDomainKey> {
/** The entity manager. */
@PersistenceContext
private EntityManager entityManager;
/** The Constant LOGGER. */
private static final Logger LOGGER = Logger.getLogger(AbstractRepository.class.getName());

/**
 * Persist the given object at persistence storage.
 *
 * @param object
 *            The object extending {@link AbstractDomainObject} which needs
 *            to be inserted.
 * @return object of type {@link AbstractDomainObject} with the newly
 *         generated id.
 * @throws Exception
 *             If unable to insert data.
 */
public T create(T object) throws Exception {
    final Session session = entityManager.unwrap(Session.class);
    session.getTransaction().begin();
    session.save(object);
    session.flush();
    session.getTransaction().commit();
    session.close();
    LOGGER.fine("Entity CREATED successfully.");
    return object;
};

1 个答案:

答案 0 :(得分:0)

让我给你一个可操作的嵌入式关键示例。它可能有所帮助。 首先覆盖等于()和 hashCode ()方法,以便Hibernate正确识别现金中的对象。

enter image description here

现在你可以持久化对象

enter image description here

如果这有帮助,或者您对此有其他问题,请告诉我。