我有2个实体 - 媒体和关键字与一对多的关系。虽然我标记为Lazy Madia的抓取仍然获取所有关键字。懒惰加载一对多不工作
我使用弹簧3.2休眠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();
}
.
.
.
}
延迟加载是OneToMany的默认获取策略,无需手动指定。这就是说,它被拿来如何?在一个巨大的联接查询中或在几个查询中?打开SQL日志记录来查看实际情况。 – Gimby