我有2个实体 - 具有一对多关系的媒体和关键字。我虽然标记了对Lazy Madia的提取仍然取得所有关键字。
我使用的是Spring 3.2 Hibernate 4.3.4
媒体实体:
@Entity
public class Media {
@Id
@NotNull
@Column(name = "mediaid")
private String mediaId;
@NotNull
@OneToMany(cascade = CascadeType.ALL, mappedBy = "media", fetch = FetchType.LAZY)
private List<Keyword> keywords;
public List<Keyword> getKeywords() {
return keywords;
}
public void setKeywords(List<Keyword> keywords) {
if ( this.keywords!=null && this.keywords.size()>0 )
this.keywords.addAll(keywords);
else
this.keywords = keywords;
for (Keyword keyword : keywords) {
keyword.setMedia(this);
}
}
}
关键字实体:
@Entity(name = "keywords")
public class Keyword {
@Id
@NotNull
@Column(unique = true)
private String idKey;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "idmedia")
private Media media;
public Media getMedia() {
return media;
}
public void setMedia(Media media) {
this.media = media;
if (idKey == null || idKey.isEmpty())
setIdKey(this.media.getMediaId());
else
setIdKey(this.media.getMediaId() + "_" + idKey);
if (!media.containsKeyword(this))
media.getKeywords().add(this);
}
}
我可以在show_sql输出中看到实体被提取,但是这个测试也失败了
@WebAppConfiguration
@ContextConfiguration(classes = {PersistenceConfig.class})
@Transactional
@TransactionConfiguration(defaultRollback = true)
public class MediasRepositoryTest extends AbstractTransactionalTestNGSpringContextTests {
@Autowired
MediasRepository mediasRepository;
@PersistenceContext
EntityManager manager;
public void thatMediaLazyLoadsKeywords() throws Exception {
PersistenceUnitUtil unitUtil = manager.getEntityManagerFactory().getPersistenceUnitUtil();
Media media = DomainFixtures.createMedia();
Media savedMedia = mediasRepository.save(media);
Media retrievedMedia = mediasRepository.findOne(savedMedia.getMediaId());
assertNotNull(retrievedMedia);
assertFalse(unitUtil.isLoaded(retrievedMedia, "keywords"));
}
}
配置:
@EnableTransactionManagement
public class PersistenceConfig {
static Logger logger = LoggerFactory.getLogger(PersistenceConfig.class);
@Autowired
private Environment env;
// @Value("${init-db:false}")
private String initDatabase = "false";
@Bean
public DataSource dataSource()
{
logger.info("Starting dataSource");
BasicDataSource dataSource = new BasicDataSource();
logger.info("jdbc.driverClassName"+ env.getProperty("jdbc.driverClassName"));
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.username"));
dataSource.setPassword(env.getProperty("jdbc.password"));
logger.info("End dataSource");
return dataSource;
}
@Bean
public EntityManagerFactory entityManagerFactory() throws SQLException
{
logger.info("Starting entityManagerFactory");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(Boolean.TRUE);
vendorAdapter.setShowSql(Boolean.parseBoolean(env.getProperty("hibernate.show_sql")));
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("....");
factory.setDataSource(dataSource());
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
jpaProperties.put("hibernate.enable_lazy_load_no_trans", true);
jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
factory.setJpaProperties(jpaProperties);
factory.afterPropertiesSet();
logger.info("End entityManagerFactory");
return factory.getObject();
}
.
.
.
}
答案 0 :(得分:1)
您的测试是在单个事务的上下文中运行。
关键字未被提取,它们仍然处于创建它们时的持久性上下文中。
尝试在保存方法调用后添加manager.clear()。
答案 1 :(得分:0)
FetchType.LAZY
只是对持久性提供程序的提示,它不是您可以信赖的设置。持久性提供程序可以随时加载属性。
因此,您无法可靠地测试延迟加载是否按预期工作。