Spring Hibernate:实体似乎没有持久化,也没有失败

时间:2014-05-23 03:37:39

标签: java spring entity-framework hibernate jpa

我的模特是

import javax.annotation.Nonnull;
import javax.persistence.Entity;

import org.joda.time.DateTime;

@Entity
public class Network extends AbstractEntity {
    private long networkId;

    private String name;

    private boolean active;

    private DateTime createdAt;

    private String createdBy;

    private DateTime updatedAt;

    private String updatedBy;
    ...
}

AbstractEntity

@MappedSuperclass
public class AbstractEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    public Long getId() {
        return id;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }

        final AbstractEntity abstractEntity = (AbstractEntity) obj;

        return id.equals(abstractEntity.id);

    }

    @Override
    public int hashCode() {
        return id == null ? 0 : id.hashCode();
    }
}

我有Repository我要添加实体的地方。我做了

@Repository
public class NetworkRepositoryImpl implements NetworkRepository {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    @Nonnull
    public List<Network> findAll() {
        //noinspection JpaQlInspection
        final Query query = entityManager.createQuery("SELECT e FROM Network e");
        return (List<Network>)query.getResultList();
    }

    @Nonnull
    @Override
    @Transactional
    public Network save(@Nonnull final Network network) {
        if (network.getId() == null) {
            entityManager.persist(network);
            return network;
        } else {
            return entityManager.merge(network);
        }
    }
}

Test

@Test
public void testAllNetworks() {
    final Network network = new Network(1, "US", true, DateTime.now());
    final Network networkInDb = networkRepository.save(network);
    assertNotNull(networkInDb.getId());
    final List<Network> networks = networkRepository.findAll();
    assertTrue(networks.isEmpty());
}

我的ApplicationConfig看起来像

@Configuration
@ComponentScan
@EnableJpaRepositories
public class ApplicationConfig {
    @Bean
    public DataSource dataSource() {
        final EmbeddedDatabaseBuilder embeddedDatabaseBuilder = new EmbeddedDatabaseBuilder();
        embeddedDatabaseBuilder.setType(EmbeddedDatabaseType.H2);
        return embeddedDatabaseBuilder.build();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        final HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
        jpaVendorAdapter.setDatabase(Database.H2);
        jpaVendorAdapter.setGenerateDdl(true);

        final LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
        localContainerEntityManagerFactoryBean.setPackagesToScan("com.org.comma.persistence");
        localContainerEntityManagerFactoryBean.setDataSource(dataSource());
        localContainerEntityManagerFactoryBean.setPersistenceUnitName("test-comma-pu");

        return localContainerEntityManagerFactoryBean;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
        return transactionManager;
    }
}

我的测试在线失败

    assertNotNull(networkInDb.getId());

意味着实体不是持久的

我在这里做错了什么?

2 个答案:

答案 0 :(得分:1)

就我而言,我使用了错误的注释。

我正在使用

import javax.transaction.Transactional;

相反,我需要的是

import org.springframework.transaction.annotation.Transactional;

至少我看到它试图坚持并在其他地方失败

答案 1 :(得分:0)

如果您的测试失败,因为Id值为null,那么它就是预期的行为。

当hibernate持久保存实体时,它不会自动获取自动生成的键值。您应该再次找到该实体或手动刷新它。

在类似的情况下,我通常刷新下面的实体。

entityManager.persist(network);
entityManager.flush();
entityManager.refresh(network);

P.S:你应该在刷新之前冲洗,以使其可靠。