【发布时间】:2018-02-06 06:39:32
【问题描述】:
考虑一个例子,我有两个实体如下
-
属性.java
@Entity @Table(name = "attribute") public class Attribute { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Getter private Long id;
}@Column(name="name") @Getter private String name; @Column(name = "source") @Getter private String source; protected Attribute(){} public Attribute(final String name, final String source) { this.name = name; this.source = source; } -
AttributeGroup.java
@Entity @Table(name = "attribute_group") public class AttributeGroup {@Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Getter private Long id; @Column(name="name") @Getter private String name; @Column(name = "value") @Getter private String value; @Getter @Column(name="attribute_id", nullable=false) protected Long attributeId; @Getter @OneToOne(optional=true, fetch = FetchType.EAGER) @JoinColumn(name="attribute_id", updatable=false, insertable=false, referencedColumnName="id") private Attribute attribute; protected AttributeGroup(){} }
两个仓库
-
AttributeRepository.java
public interface AttributeRepository{} -
AttributeGroupRepository.java
public interface AttributeGroupRepository {
}/** * find list of Groups by attribute name * @param attribute * @return */ List<AttributeGroup> findByAttribute(Attribute attribute);
AttributeGroupRepositoryTest.java
<pre><code>@RunWith(SpringRunner.class)
@DataJpaTest
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
TransactionalTestExecutionListener.class, DbUnitTestExecutionListener.class})
@DatabaseSetup(AttributeGroupRepositoryTest.DATASET)
@DatabaseTearDown(type = DatabaseOperation.CLEAN_INSERT, value = { AttributeGroupRepositoryTest.DATASET })
public class AttributeGroupRepositoryTest {
protected static final String DATASET = "classpath:/attribute-group-test-data.xml";
@Autowired
private AttributeGroupRepository groupRepository;
@Test
public void findByAttributes(){
Attribute attribute=new Attribute("Data","abc");
List<AttributeGroup> groups = groupRepository.findByAttribute(attribute);
assertThat(groups.isEmpty(), Matchers.is(false));
assertThat(groups.size(), Matchers.equalTo(2));
assertThat(groups.stream().findFirst().get().getId(), Matchers.equalTo(5L));
assertThat(groups.stream().findFirst().get().getName(), Matchers.equalTo("GROUP1"));
assertThat(groups.stream().findFirst().get().getValue(), Matchers.equalTo("HW"));
assertThat(groups.stream().findFirst().get().getAttribute().getId(), Matchers.equalTo(3L));
assertThat(groups.stream().findFirst().get().getAttribute().getName(), Matchers.equalTo("Data"));
assertThat(groups.stream().findFirst().get().getAttribute().getSource(), Matchers.equalTo("abc"));
}
}
xml文件
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<lima_attribute id="1" name="Issuer Ultimate Parent Name" source="VENTURE"/>
<lima_attribute id="2" name="Currency" source="abc"/>
<lima_attribute id="3" name="Data" source="abc"/>
<lima_attribute_group id="1" name="CurrencyGroup" value="AUS" attribute_id="2"/>
<lima_attribute_group id="2" name="CurrencyGroup" value="GBP" attribute_id="2"/>
<lima_attribute_group id="3" name="CurrencyGroup" value="BHD" attribute_id="2"/>
<lima_attribute_group id="4" name="CurrencyGroup" value="AFA" attribute_id="2"/>
<lima_attribute_group id="5" name="GROUP1" value="HW" attribute_id="3"/>
<lima_attribute_group id="6" name="GROUP1" value="VOL" attribute_id="3"/>
</dataset>
以上测试用例抛出异常
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.entity.attribute.Attribute; nested exception is java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.entity.attribute.Attribute
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:381)
Caused by: java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.entity.attribute.Attribute
由于此测试依赖于属性存储库,而 Junit 是单元测试用例,我不想使用属性存储库。
还有其他方法可以模拟其他存储库数据吗?
【问题讨论】:
-
问题似乎是您创建并传递给 find 方法的 Attribute 对象。你能重写 findByAttributeName 的方法,只传递名称,看看会发生什么?
标签: java spring unit-testing junit spring-data-jpa