1

Page、ProfileSection、および PageComponents との 3 つの多対多マッピングを持つロール エンティティがあります。Role ページをロードすると、適切にロードされますが、profileSection と PageComponents は 1 つのレコードしかロードしません。

以下は私のモデルです。

@Entity 
@Table(name = "role", uniqueConstraints = {@UniqueConstraint(columnNames={"authority"})})
public class Role extends AbstractBaseModel implements GrantedAuthority {
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO)
    @BusinessKey(include = MethodType.TO_STRING)
    private int id;

    @BusinessKey
    private String authority;

    @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    //@Fetch(value = FetchMode.SUBSELECT)
    private Set<Page> pages;

    @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    //@Fetch(value = FetchMode.SUBSELECT)
    private Set<PageComponent> pageComponents;

    @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    @Fetch(value = FetchMode.SELECT)
    private Set<ProfileSection> profileSections;
}

Page.java

@XmlRootElement(name="page")
@Entity
@Table(name = "page", catalog = "public", uniqueConstraints = {@UniqueConstraint(columnNames = {"page_id", "page_title"})})
public class Page extends OrderedModel {
    private static final long serialVersionUID = 1L;

    @BusinessKey(include = MethodType.TO_STRING)
    @Column(name = "page_id")
    private String pageId;

    @BusinessKey(include = MethodType.TO_STRING)
    @Column(name = "page_title")
    private String pageTitle;

    @BusinessKey
    @OneToMany(mappedBy="page", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<PageComponent> pageComponents;
}

ProfileSection.java

@Entity
@Table(name = "profile_section", catalog = "public", uniqueConstraints = {@UniqueConstraint(columnNames = "section_id")})
public class ProfileSection  extends OrderedModel {
    private static final long serialVersionUID = 1L;

    @BusinessKey(include = MethodType.TO_STRING)
    @Column(name = "section_id")
    private String sectionId;

    @BusinessKey(include = MethodType.TO_STRING)
    @Column(name = "section_title")
    private String sectionTitle;
}

PageComponent.java

@Entity
@Table(name = "page_component", catalog = "public", uniqueConstraints = {@UniqueConstraint(columnNames = "component_id")})
public class PageComponent  extends BaseModel {
    private static final long serialVersionUID = 1L;

    @BusinessKey
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="page_id")
    private Page page;

    @BusinessKey(include = MethodType.TO_STRING)
    @Column(name = "component_id")
    private String componentId;

    @BusinessKey(include = MethodType.TO_STRING)
    @Column(name = "component_title")
    private String componentTitle;

    @BusinessKey(include = MethodType.TO_STRING)
    @Column(name = "component_type")
    private String componentType;
}

そして、私のdaoの次のコード

List<Person> list = c.list();
for(Person p: list){
    System.out.println("Roles size is:: "+p.getRoles().size());
    Role r = p.getRoles().iterator().next();
    System.out.println("Page Size is: "+r.getPages().size());
    System.out.println("ProfileSection Size is: "+r.getProfileSections().size());
    System.out.println("Page Components Size is: "+r.getPageComponents().size());
    for(ProfileSection s : r.getProfileSections()) {
        System.out.println(s.getSectionId());
    }
}

結果は次のとおりです。

Roles size is:: 1 - Expected 1

Page Size is: 6 - Expected 6

ProfileSection Size is: 1 - Expected 3

Page Components Size is: 1 - Expected 4

あなたが提供したリンクに従って Role.java を変更しました。以下は変更されたエンティティです

@Entity 
@Table(name = "role", uniqueConstraints = {@UniqueConstraint(columnNames={"authority"})})
public class Role extends AbstractBaseModel implements GrantedAuthority{


    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO)
    @BusinessKey(include = MethodType.TO_STRING)
    private int id;

    @BusinessKey
    private String authority;

    @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name="role_page",
      joinColumns={@JoinColumn(name="role_id", referencedColumnName="id")},
      inverseJoinColumns={@JoinColumn(name="pages_id", referencedColumnName="id")})
    private Set<Page> pages;

    @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name="role_page_component",
      joinColumns={@JoinColumn(name="role_id", referencedColumnName="id")},
      inverseJoinColumns={@JoinColumn(name="pagecomponents_id", referencedColumnName="id")})
    private Set<PageComponent> pageComponents;

    @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name="role_profile_section",
      joinColumns={@JoinColumn(name="role_id", referencedColumnName="id")},
      inverseJoinColumns={@JoinColumn(name="profilesections_id", referencedColumnName="id")})
    private Set<ProfileSection> profileSections;

}

以下はdaoコードです:

/**
     * For Depth > 1, better use this method method.
     * Example: Person person = personDAO.findByProperty("email", email, lazyOptions, true);
     */
    @SuppressWarnings("unchecked")
    public T findByProperty(String propertyName, Object value, HibernateCriteriaLazyOptions lazyOptions, boolean uniqueResult) {
        JoinCriteriaHelper joiner = JoinCriteriaHelper.forClass(getGenericClass(), lazyOptions.getPaths());
        Criteria c;
        if(lazyOptions.getDepth() != null){
            // this would only fetch properties a, b and e
            c = joiner.getExecutableCriteria(getSession(), lazyOptions.getDepth());
            //DetachedCriteria dc = joiner.getDetachedCriteria(Preload.DEPTH_2);
        }else{
            // this would fetch all properties a, b, c, d and e
            c = joiner.getExecutableCriteria(getSession());
        }
        c.add(Restrictions.eq(propertyName, value));

        if(getGenericClass().equals(Person.class)){
            List<Person> list = c.list();
            for(Person p: list){
                System.out.println("Roles size is:: "+p.getRoles().size());
                Role r = p.getRoles().iterator().next();
                System.out.println("Page Size is: "+r.getPages().size());
                System.out.println("ProfileSection Size is: "+r.getProfileSections().size());
                System.out.println("Page Components Size is: "+r.getPageComponents().size());
                for(ProfileSection s : r.getProfileSections()){
                    System.out.println(s.getSectionId());
                }
            }
        }
        return (T)UnproxyUtility.unproxy((T)c.uniqueResult());
    }

以下は私のテーブルです:

CREATE TABLE "role"
(
  id integer NOT NULL,
  authority character varying(255),
  CONSTRAINT role_pkey PRIMARY KEY (id),
  CONSTRAINT role_authority_key UNIQUE (authority)
)

CREATE TABLE page
(
  id bigserial NOT NULL,
  created_date timestamp without time zone,
  last_updated timestamp without time zone,
  page_id character varying(255),
  page_title character varying(255),
  order_number bigint,
  CONSTRAINT page_pkey PRIMARY KEY (id),
  CONSTRAINT page_page_id_key UNIQUE (page_id),
  CONSTRAINT page_page_id_key1 UNIQUE (page_id),
  CONSTRAINT page_page_title_key UNIQUE (page_title)
)

CREATE TABLE role_page
(
  role_id integer NOT NULL,
  pages_id bigint NOT NULL,
  CONSTRAINT role_page_pkey PRIMARY KEY (role_id, pages_id),
  CONSTRAINT fk140574b8dc0483c9 FOREIGN KEY (pages_id)
      REFERENCES page (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fk140574b8facefbbe FOREIGN KEY (role_id)
      REFERENCES "role" (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

CREATE TABLE page_component
(
  id bigserial NOT NULL,
  created_date timestamp without time zone,
  last_updated timestamp without time zone,
  component_id character varying(255),
  component_title character varying(255),
  component_type character varying(255),
  page_id bigint,
  CONSTRAINT page_component_pkey PRIMARY KEY (id),
  CONSTRAINT fk5b31d34d78d7191e FOREIGN KEY (page_id)
      REFERENCES page (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT page_component_component_id_key UNIQUE (component_id)
)

CREATE TABLE role_page_component
(
  role_id integer NOT NULL,
  pagecomponents_id bigint NOT NULL,
  CONSTRAINT role_page_component_pkey PRIMARY KEY (role_id, pagecomponents_id),
  CONSTRAINT fk8af50636d6882e9f FOREIGN KEY (pagecomponents_id)
      REFERENCES page_component (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fk8af50636facefbbe FOREIGN KEY (role_id)
      REFERENCES "role" (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

CREATE TABLE profile_section
(
  id bigserial NOT NULL,
  created_date timestamp without time zone,
  last_updated timestamp without time zone,
  order_number bigint,
  section_id character varying(255),
  section_title character varying(255),
  CONSTRAINT profile_section_pkey PRIMARY KEY (id),
  CONSTRAINT profile_section_section_id_key UNIQUE (section_id),
  CONSTRAINT profile_section_section_id_key1 UNIQUE (section_id)
)

CREATE TABLE role_profile_section
(
  role_id integer NOT NULL,
  profilesections_id bigint NOT NULL,
  CONSTRAINT role_profile_section_pkey PRIMARY KEY (role_id, profilesections_id),
  CONSTRAINT fkcac52086b893cd43 FOREIGN KEY (profilesections_id)
      REFERENCES profile_section (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fkcac52086facefbbe FOREIGN KEY (role_id)
      REFERENCES "role" (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

以下は、Hibernate によって実行されるクエリです。

Hibernate: select pages0_.role_id as role1_22_1_, pages0_.pages_id as pages2_1_, page1_.ID as ID17_0_, page1_.created_date as created2_17_0_, page1_.last_updated as last3_17_0_, page1_.order_number as order4_17_0_, page1_.page_id as page5_17_0_, page1_.page_title as page6_17_0_ from role_page pages0_ inner join public.page page1_ on pages0_.pages_id=page1_.ID where pages0_.role_id=?

Page Size is: 6

Hibernate: select profilesec0_.role_id as role1_22_1_, profilesec0_.profilesections_id as profiles2_1_, profilesec1_.ID as ID19_0_, profilesec1_.created_date as created2_19_0_, profilesec1_.last_updated as last3_19_0_, profilesec1_.order_number as order4_19_0_, profilesec1_.section_id as section5_19_0_, profilesec1_.section_title as section6_19_0_ from role_profile_section profilesec0_ inner join public.profile_section profilesec1_ on profilesec0_.profilesections_id=profilesec1_.ID where profilesec0_.role_id=?

ProfileSection Size is: 1

Hibernate: select pagecompon0_.role_id as role1_22_1_, pagecompon0_.pagecomponents_id as pagecomp2_1_, pagecompon1_.ID as ID18_0_, pagecompon1_.created_date as created2_18_0_, pagecompon1_.last_updated as last3_18_0_, pagecompon1_.component_id as component4_18_0_, pagecompon1_.component_title as component5_18_0_, pagecompon1_.component_type as component6_18_0_, pagecompon1_.page_id as page7_18_0_ from role_page_component pagecompon0_ inner join public.page_component pagecompon1_ on pagecompon0_.pagecomponents_id=pagecompon1_.ID where pagecompon0_.role_id=?

Page Components Size is: 1

結果を確認する場合:

Pages are getting 6 - This is expected as the rows are 6 for that particular role id

PageComponents 1 - This is wrong as the rows matching for that role id are 4

ProfileSections 1 - This is also wrong matching rows are 4.

どこが間違っているのか理解できません。提案に従ってエンティティを更新しましたが、それでも結果は期待どおりではありません。多対多に取り組むのはこれが初めてではありません。これまで、この種の問題は発生していません。Role.javaでjoinTableをマッピングしなくても、期待どおりの結果が得られました。

私が間違っているときは教えてください。

4

1 に答える 1

0

PageProfileSection、またはまったく返される理由が正確にはわかりませんPageComponent@JoinTable注釈を使用して多対多を接続しているようには見えません@JoinColumn。おそらくXML経由でやっていますか?その場合、結合定義を投稿できますか?

注釈を使用して ManyToMany を接続する手順については、このサイトを参照してください。

于 2012-04-06T22:53:25.190 に答える