4

それが指すエンティティのバーコードの文字列値を持つテーブルがあります。残念ながら、これは外部キーではなく単なる文字列であるため、マッピングは存在しません。これにより、結合操作が困難になります。このオブジェクトを、関係が定義されていない別のテーブルに結合する方法を考えていました。例えば:

@Entity
@Table(name = "TblSample", schema = SCHEMA, catalog = CATALOG)
public class Sample {

  @Id
  @Column(name = "id", nullable = false)
  private int id;

  @Column(name = "barcodeEntity", nullable = false)
  private String barcodeEntity;

  @OneToOne
  @JoinColumn(name = "barcodeContainer", nullable = false)
  private Container container;

  ...
}

@Entity
@Table(name = "TblSoil", schema = SCHEMA, catalog = CATALOG)
public class Soil {

  @Column(name = "barcode", nullable = false)
  private String barcode;

  @Column(name = "name", nullable = false)
  private String name;
  ...

}

@Entity
@Table(name = "TblLeaf", schema = SCHEMA, catalog = CATALOG)
public class Leaf {

  @Column(name = "barcode", nullable = false)
  private String barcode;

  @Column(name = "name", nullable = false)
  private String name;
  ...
}

@Entity
@Table(name = "TblContainer", schema = SCHEMA, catalog = CATALOG)
public class Container {

  @Column(name = "barcode", nullable = false)
  private String barcode;

  @Column(name = "name", nullable = false)
  private String name;

  @Column(name = "location", nullable = false)
  private String location;
  ...
}

したがって、CriteriaQuery を使用して、すべてのサンプルを返し、それが取得されたエンティティに結合できるようにしたいと思います。私はそれを書き始めましたが、それを行う方法を理解しようとすると行き詰まりました。SQLでは、次のようなものが必要です:

SELECT TOP 100
  sample.Id
, sample.barcodeEntity
, leaf.name
, soil.name
, sample.barcodeContainer
, container.name
, container.location
FROM TblSample sample

  LEFT JOIN TblSoil leaf on
    soil.barcode = sample.barcodeEntity

  LEFT JOIN TblLeaf leaf on
    leaf.barcode = sample.barcodeEntity

  JOIN TblContainer container on
    container.barcode = sample.barcodeContainer

関連する jpa CriteriaQuery は次のようになると思います。

public void findSamples(Map<String, String> filterCriteria) {
    final CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
    final CriteriaQuery<SampleLocation> query = builder.createQuery(SampleLocation.class);
    final Root<Sample> derivation = query.from(Sample.class);
    // Note that the next two lines don't work 
    final Join<Leaf> joinOnLeaf = derivation.join(Sample_.barcodeEntity, JoinType.LEFT);
    final Join<Soil> joinOnSoil = derivation.join(Sample_.barcodeEntity, JoinType.LEFT);
    final Join<Container> joinOnContainer = derivation.join(Sample_.barcodeContainer);

    CompoundSelection<SampleLocation> cSelect = 
      builder.construct(SampleLocation.class, sample.Id, sample.entitybarcode, joinOnLeaf.get(Leaf_.name), joinOnLeaf.get(Soil_.name), sample.barcodeContainer, joinOnContainer.get(Container_.name), joinOnContainer.get(Container_.location));
    query.select(cSelect);

    TypedQuery<SampleLocation> typedQuery = entityManager.createQuery(query);
    typedQuery.setMaxResults(100);

    return typedQuery.getResults();
}

左結合操作を実行する方法はありますか? CriteriaQuery api に基づいてそれを行う方法がわかりません。あるべきもののようです。

4

1 に答える 1

1

2 つのクエリを提案します。最初のものについては、バーコード文字列と一致する主キー値を取得します。次に、最初のクエリのデータを 2 番目のクエリで使用します。

于 2013-02-25T13:53:04.533 に答える