Spring JPA多对多关系无法获取数据

时间:2017-07-30 03:50:13

标签: java spring hibernate jpa

我一直在使用Spring开发应用程序,而我正在使用JPA来处理数据库。我有两个实体,它们如下

合作伙伴实体

@Entity
public class Partner {

 @ManyToMany()
 private List<Tenant> tenants;

 public List<Tenant> getTenants() {
     return tenants;
 }

 public void setTenants(List<Tenant> tenants) {
     this.tenants = tenants;
 }

}

租户实体

@Entity
public class Tenant {
...
}

这两个实体已由PartnerServiceTenantService服务公开。

在另一个服务类中,我从PartnerService检索合作伙伴,当我调用partner.getTenants()时,它返回0个元素的列表。但在数据库中,特定合作伙伴有2个租户。我的服务类如下

@Service
public class DBOutboundInjector implements OutboundInjector {

 private final ApplicationContext context;

 @Autowired
 public DBOutboundInjector(ApplicationContext context) {
     this.context = context;
 }

 @Override
 @Transactional
 public boolean insertEntry(Long partnerId) {

    PartnerService partnerService = context.getBean(PartnerService.class);

            Partner partner = partnerService.getPartnerById(partnerId);
            List<Tenant> partnerTenants = partner.getTenants();
...
  }
}

2 个答案:

答案 0 :(得分:0)

请参阅以下备选方案

备选方案1:尝试使用@ManyToMany FetchType.EAGER

@Entity
public class Partner {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long id;

    public Partner() {
    }

    public Partner( String name, String location, List<Tenant> tentans) {

        this.name = name;
        this.location = location;
        this.tenants = tentans;
    }


    @ManyToMany(fetch = FetchType.EAGER)
    private List<Tenant> tenants;

备选方案2:在PartnerRepository上添加新方法以获取合作伙伴并获取相关租户对象列表。

@Repository
public interface PartnerRepository extends JpaRepository<Partner,Long> {

    @Query("SELECT p FROM Partner p JOIN FETCH p.tenants WHERE p.id=(:id)")
    public Partner findByIdFetchTenant(@Param("id") Long id);

这是如何获取租户列表的常规,您可以在您内部自动装配存储库ParentServcie

partner = partnerRepository.findByIdFetchTenant(partner.getId());
System.out.println("One Partner" + partner);
System.out.println(partner.getTenants());

修改

我正在分享完整的示例,在这种情况下我使用spring boot,web,h2数据库,spring jpa

application.properties

spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.datasource.url:jdbc:h2:mem:~/test

Partner.class

@Entity
public class Partner {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long id;

    public Partner() {
    }

    public Partner( String name, String location, List<Tenant> tentans) {

        this.name = name;
        this.location = location;
        this.tenants = tentans;
    }


    @ManyToMany(fetch = FetchType.EAGER)
    private List<Tenant> tenants;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }


    private String name;

    private String location;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public List<Tenant> getTenants() {
        return tenants;
    }

    public void setTenants(List<Tenant> tenants) {
        this.tenants = tenants;
    }

    @Override
    public String toString() {

        return "Partner{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", location='" + location + '\'' +

                '}';
    }
}

Tenant.class

@Entity
public class Tenant {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long id;

    public Tenant() {

    }

    @Override
    public String toString() {
        return "Tenant{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", description='" + description + '\'' +
                '}';
    }

    public Tenant(String name, String description) {

        this.name = name;
        this.description = description;

    }

    private String name;

    private String description;



    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }


}

PartnerRepository.class

@Repository
public interface PartnerRepository extends JpaRepository<Partner,Long> {

    @Query("SELECT p FROM Partner p JOIN FETCH p.tenants WHERE p.id=(:id)")
    public Partner findByIdFetchTenant(@Param("id") Long id);

}

TenantRepository.class

@Repository
public interface TenantRepository  extends JpaRepository<Tenant,Long> {
}

MyApp.class的

@SpringBootApplication
public class MyApp {

    private static final Logger logger = LoggerFactory.getLogger(MyApp.class);

    public static void main(String[] args) {
           SpringApplication.run(MyApp.class, args);
    }


    @Bean
    public CommandLineRunner runner(TenantRepository tenantRepository, PartnerRepository partnerRepository){
        return (args) -> {

            logger.info("Creating Data Many to Many...");
            Tenant tenant1,tenant2,tenant3 = null;
            Partner partner=null;


            tenant1 = new Tenant("tenant1","tenant1");
            tenant2 = new Tenant("tenant2","tenant2");
            tenant3 = new Tenant("tenant3","tenant3");
            tenantRepository.save(tenant1);
            tenantRepository.save(tenant2);
            tenantRepository.save(tenant3);

            partner = new Partner("partner1","partner location", Arrays.asList(tenant1,tenant2,tenant3));
            partnerRepository.save(partner);

            partner = partnerRepository.findByIdFetchTenant(partner.getId());

            System.out.println("One Partner" + partner);
            System.out.println(partner.getTenants());

        };}}

的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.boot.spring</groupId>
    <artifactId>myjpademo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>myjpademo</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

问候。

答案 1 :(得分:0)

按照示例打击。学生与学科之间存在着许多关系。

@Entity
public class Student{
    private int id;
    private String name;
    private Set<Subject> subjects;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public int getId() {
        return id;
    }


    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "student_subject", joinColumns = @JoinColumn(name = "student_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "subject_id", referencedColumnName = "id"))
    public Set<Subject> getSubjects() {
        return subjects;
    }

    public void setSubjects(Set<Subject> subjects) {
        this.subjects = subjects;
    }

}

@Entity
public class Subject {
    private int id;
    private String name;
    private Set<Student> students;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public int getId() {
        return id;
    }

    @ManyToMany(mappedBy = "subjects")
    public Set<Student> getStudents() {
        return students;
    }

 }

从帖子many to many relationship in spring data jpa

中找到此信息