Java Hibernate多对多结果与预期不符-仅获取最后一条记录

Java Hibernate多对多结果与预期不符-仅获取最后一条记录,java,hibernate,many-to-many,Java,Hibernate,Many To Many,我有一个角色实体,它有三个与Page、ProfileSection和PageComponents的多对多映射。当我加载角色时,页面加载正确,但profileSection和PageComponents仅加载一条记录 下面是我的模型 @Entity @Table(name = "role", uniqueConstraints = {@UniqueConstraint(columnNames={"authority"})}) public class Role extends AbstractB

我有一个角色实体,它有三个与Page、ProfileSection和PageComponents的多对多映射。当我加载角色时,页面加载正确,但profileSection和PageComponents仅加载一条记录

下面是我的模型

@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;
}
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());
    }
}

我根据您提供的链接修改了我的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;

}
以下是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,也得到了预期的结果


请告诉我什么时候我错了?

我不太清楚为什么它会返回
页面
配置文件部分
,或者
页面组件
。看起来你并没有用
@JoinTable
@jointcolumn
注释将你的多对多连接起来。也许您是通过XML实现的?在这种情况下,您可以发布您的联接定义吗


请参阅,以获取有关将多个注释与多个注释连接起来的说明。

填充时是否可以显示代码,或者打印连接表?我发布了我的代码。请看一看。我添加了我的评论,请看一看。我不熟悉
JoinCriteriaHelper
,但考虑到它部分地限制了初始化(),这肯定是您的问题的根源。您是否尝试过使用老式的
@NamedQuery
进行获取,以查看默认的Hibernate行为产生了什么?我将集合映射从Set更改为List。现在我得到了所有的行。为什么在使用Set映射集合时只得到最后一行?对于所有
ProfileSection
PageComponent
对象,
hashcode()
是否返回相同的值?这可以解释一切。
@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;

}
/**
     * 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: 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.