我使用spring数据jpa,休眠时我有一个复杂的结构。我搜索以获取带有某些对象的样本
Option Explicit
Sub searchPrefix()
Sheets("PREFIXES").Select
Dim CellCntnt As String
Dim tmpSrch As String
Dim isFound As Boolean
isFound = False
Dim QtySrchChar As Integer
QtySrchChar = 4
Dim Cnt As Integer
Cnt = 0
Dim Tag As Integer
Cells.Range("A1").Select
Do Until IsEmpty(ActiveCell)
Cnt = Cnt + 1
ActiveCell.Offset(1, 0).Select
Loop
For Tag = 1 To Cnt - 1
CellCntnt = Cells(1 + i, 1).Value
tmpSrch = Left(CellCntnt, QtySrchChar)
Cells.Range("G1").Select
Do Until IsEmpty(ActiveCell)
If Left(ActiveCell.Value, QtySrchChar) = tmpSrch Then
QtySrchChar = QtySrchChar + 1
tmpSrch = Left(CellCntnt, QtySrchChar)
isFound = True
MsgBox ("True Tags introduced with Std.Prefix " & tmpSrch)
End If
If isFound Then
isFound = False
MsgBox ("False Tags introduced with Std.Prefix " & tmpSrch)
Cells.Range("G1").Select
Else
ActiveCell.Offset(1, 0).Select
End If
Loop
Next Tag
End Sub
当我保存新样本时,我会做
@Entity
@IdClass(SamplingsPK.class)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Samplings {
@Id
private int year;
@Id
@GeneratedValue
private Integer sequenceId;
@OneToOne
private Products product;
@OneToOne
private Machines machine;
@OneToOne
private Dimensions dimension;
@OneToOne
private Colors color;
@OneToMany(mappedBy = "sampling", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Samples> samples = new ArrayList<>();
...
}
@Entity
@IdClass(SamplesPK.class)
public class Samples extends BaseEntity {
@Id
private String sampleLetter;
@Id
@ManyToOne(optional = false)
@JoinColumns({
@JoinColumn(name = "sampling_id", referencedColumnName = "sequenceId"),
@JoinColumn(name = "sampling_year", referencedColumnName = "year")})
private Samplings sampling;
@OneToOne(mappedBy = "sample", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
//@JoinColumns({
// @JoinColumn(name = "sampling_id", referencedColumnName = "sequenceId"),
// @JoinColumn(name = "sampling_year", referencedColumnName = "year")})
private TestSamples testSamples;
...
}
public class SamplesPK implements Serializable {
private SamplingsPK sampling;
private String sampleLetter;
public SamplesPK(SamplingsPK sampling, String sampleLetter) {
this.sampling = sampling;
this.sampleLetter = sampleLetter;
}
private SamplesPK() {
}
}
@Entity
public class TestSamples {
@Id
@SequenceGenerator(name = "test_samples_id_seq", sequenceName = "test_samples_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "test_samples_id_seq")
private Integer id;
@OneToOne(fetch = FetchType.LAZY)
private Samples sample;
@OneToOne(mappedBy = "testSample", fetch = FetchType.LAZY)
private Compressions compressionTest;
@OneToOne(mappedBy = "testSample", fetch = FetchType.LAZY)
private Durabilities durabilityTest;
@OneToOne(mappedBy = "testSample", fetch = FetchType.LAZY)
private Scalings scalingTest;
@OneToOne(mappedBy = "testSample", fetch = FetchType.LAZY)
private Granulometries granulometryTest;
@OneToOne(fetch = FetchType.LAZY)
private Absorptions absorptionTest;
...
}
保存后,如果尝试使用testSample获取样本,则运行此查询
Samplings sampling = new Samplings();
..
Samples sample = new Samples();
...
TestSamples testSamples = new TestSamples();
testSamples.setSample(sample);
..
sample.setTestSamples(testSamples);
samplings.addSample(sample);
samplings = samplingsRepository.save(sampling);
当我检查样本时,TestSamples始终为空
我发现一个非常糟糕的解决方法...
@Query(
value = "select s from Samples s Join fetch s.sampling sp Left Join fetch sp.machine m Join fetch sp.product p Join fetch p.productType pt Join Fetch s.testSamples",
countQuery = "select count(s) from Samples s Join s.sampling sp Left Join sp.machine m Join sp.product p Join p.productType Join s.testSamples")
public Page<Samples> findAllFullSample(Pageable pageable);
查询代码
Page<Samples> pageSamples = samplesRepository.findAllFullSample(pageable);
List<Samples> samples = pageSamples.getContent();
for (Samples sample : samples) {
TestSamples testSample= testSamplesRepository.findSamplesWithFullProductAndCompressionTest(sample.getSampling().getSequenceId(),sample.getSampling().getYear(), sample.getSampleLetter());
sample.setTestSamples(testSample);
}
return pageSamples;
那为什么当我从Sample中获取TestSample时为null
答案 0 :(得分:0)
我认为您的映射不正确。
当我查看Samples类时,会看到:
@OneToOne(mappedBy = "sample", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
@JoinColumns({
@JoinColumn(name = "sampling_id", referencedColumnName = "sequenceId"),
@JoinColumn(name = "sampling_year", referencedColumnName = "year")})
private TestSamples testSamples;
...
这看起来像是采样映射中的复制过去。
您应该先检查映射是否正确。
您是否从映射生成表?如果是,请检查生成的表是否符合预期。
答案 1 :(得分:0)
不确定这是否是答案-我针对示例类和示例代码进行了尝试:
Samplings sampling = new Samplings();
sampling.setYear(2018);
Samples sample = new Samples();
sample.setSampling(sampling);
sample.setSampleLetter("A");
TestSamples testSamples = new TestSamples();
testSamples.setSample(sample);
sample.setTestSamples(testSamples);
sampling.addSample(sample);
sampling = samplingsRepository.save(sampling);
EntityManager em = ...;
em.flush();
em.clear();
Pageable pageable = Pageable.unpaged();
Page<Samples> samples = repository.findAllFullSample(pageable);
Samples firstSampleBack = samples.getContent().get(0);
System.out
.println("--> testSamples=" + firstSampleBack.getTestSamples());
这成功返回了相关的TestSamples:
--> testSamples=TestSamples [id=1]
该测试注释掉了这三个类别之外的其他所有类别,包括查询在内,我不知道是否还需要其他什么来重现您所看到的问题。
似乎最容易完整地发布该工作示例。也许这至少将提供一个可供比较的选择。
https://github.com/df789/samples-query
这是针对Spring Boot和H2内存数据库的,因此应该独立运行。例如。 mvn clean test
足以看到上面的测试用例。
修改
要继续执行下面Robert的评论,经过一点调试,Hibernate似乎比较了@Entity
上的类型和@IdClass
上的匹配字段,并尝试以任何一种方式进行。可以在源here中找到此检查。
如果PK上的类型匹配,则使用NormalMappedIdentifierValueMarshaller
来构造PK标识符值。如果不这样做,似乎会尽最大努力继续使用命名明确的IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller
。似乎从那里开始,代码沿混合类型走了一条“不太麻烦的路”-显然可以进行保存,但是稍后会发现一些惊喜。