2015-07-01 20 views
7

Provo a configurare OneToMany e ManyToOne nel progetto Spring Data ma ho alcuni problemi.Dati primari mappatura uno a molti

Quindi ho due entità: Datore di lavoro e Progetto. Un datore di lavoro potrebbe avere molti progetti.

classi di entità:

Employer.java

@Entity 
@Table (name="Employer") 
public class Employer { 

    @Id 
    @SequenceGenerator(name="my_seq", sequenceName="GLOBAL_SEQUENCE") 
    @GeneratedValue(strategy = GenerationType.SEQUENCE ,generator="my_seq") 
    @Column (name="employer_id") 
    private int id; 

    @Column (name="name") 
    private String name; 

    @JoinColumn (name="employer_id") 
    @OneToMany(mappedBy = "employer", cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    private Set<Project> project = new HashSet<Project>(); 

    ...................... 
} 

Project.java

@Entity 
@Table (name="Project") 
public class Project { 

    @Id 
    @SequenceGenerator(name="my_seq", sequenceName="GLOBAL_SEQUENCE") 
    @GeneratedValue(strategy = GenerationType.SEQUENCE ,generator="my_seq") 
    @Column (name="project_id") 
    private int id; 

    @Column (name="name") 
    private String name; 

    @ManyToOne 
    @JoinColumn(name="employer_id", nullable = false) 
    private Employer employer; 
    ...................... 
} 

classi repository:

public interface EmployerRepository extends JpaRepository<Employer, Integer> { 
} 

public interface ProjectRepository extends JpaRepository<Project, Integer> { 
} 

Servizi:

@Service 
public class EmployerServiceImpl implements EmployerService { 

    @Autowired 
    private EmployerRepository employerRepository; 

    @Override 
    public List<Employer> getAllEmployers() { 
     return employerRepository.findAll(); 
    } 
} 

@Service 
public class ProjectServiceImpl implements ProjectService { 

    @Autowired 
    private ProjectRepository projectRepository; 

    @Override 
    public List<Project> getAllProjects() { 
     return projectRepository.findAll(); 
    } 
} 

Controller:

@Controller 
public class MainController { 

    private EmployerService employerService; 

    private ProjectService projectService; 

    @Autowired(required = true) 
    @Qualifier(value = "employerService") 
    public void setEmployerService(EmployerService employerService) { 
     this.employerService = employerService; 
    } 

    @Autowired(required = true) 
    @Qualifier(value = "projectService") 
    public void setProjectService(ProjectService projectService) { 
     this.projectService = projectService; 
    } 


    @RequestMapping(value="/employers", method=RequestMethod.GET) 
    public @ResponseBody List<Employer> getEmployers(@RequestParam(value = "name", required = false) String name) { 
     return employerService.getAllEmployers();   
    } 
    .............................. 
} 

tavolo di lavoro:

EMPLOYER_ID . NAME 
...................... 
1   . Google 
2   . Oracle 
3   . Facebook 

tabella Progetto:

PROJECT_ID . NAME   . EMPLOYER_ID 
....................................... 
1   . Create web site . 1 
2   . Create reporting . 2 
3   . Create web service . 3 
4   . Fixing web site . 1   

Mi aspetto qualcosa di simile:

[{"id":1,"name":"Google","project":[{"id":1,"name":"Create web site"}, {"id":4,"name":"Fixing web site"}}, 
{"id":2,"name":"Oracle","project":{"id":2,"name":"Create reporting"}}, 
{"id":3,"name":"Facebook","project":{"id":3,"name":"Create web service"}}] 

Ma getEmployers metodo dalla classe controller tornare questo:

[{"id":1,"name":"Oracle","project":[{"id":4,"name":"Fixing web site", 
"employer":{"id":1,"name":"Oracle","project":[{"id":4,"name":"Fixing web site", 
"employer":{"id":1,"name":"Oracle","project":[{"id":4,"name":"Fixing web site", 
"employer":{"id":1,"name":"Oracle","project":[{"id":4,"name":"Fixing web site", 
"employer":{"id":1,"name":"Oracle","project":[{"id":4,"name":"Fixing web site", 
"employer":{"id":1,"name":"Oracle","project":[{"id":4,"name":"Fixing web site","employer": 
................... 

Si prega di scusa se questa domanda discusso molte volte, ma io didn trovare una risposta adeguata

Grazie in anticipo!

risposta

4

Si dispone di un'associazione bidirezionale tra Employer s e Project s. Inoltre, si sono configurati entrambi i lati dell'associazione da caricare EAGER l (le associazioni @ManyToOne vengono recuperate per impostazione predefinita e si è forzato il numero @OneToMany a prelevare EAGER ly). A causa di questa configurazione, quando il framework di serializzazione carica Employer s, trova Project s validi con collegamenti di ritorno allo Employer e finisce per rimanere bloccato in un ciclo ciclico.

Al fine di ottenere il risultato desiderato, si dovrà contrassegnare il lato @ManyToOne (sull'entità Project) da prelevare LAZY mente come @ManyTone(fetch = FetchType.LAZY).

+0

Grazie per la riproduzione. Aggiungo '@ManyToOne (fetch = FetchType.LAZY)' all'entità 'Project' ma non aiuta, il risultato è lo stesso del primo. – Iurii

+0

Sembra che Jackson finisca per serializzare anche le entità pigre. [Questo post] (http://stackoverflow.com/questions/25906985/jackson-do-not-serialize-lazy-objects) ha alcune opzioni che potresti provare. – manish

+0

Ho cambiato la mia mappatura OneToMany a questo: '@JsonInclude (JsonInclude.Include.NON_EMPTY) @OneToMany (prendere = FetchType.EAGER, mappedBy = ("datore di lavoro"), cascade = CascadeType.ALL) progetto privato Set = nuovo HashSet (); 'ma non è d'aiuto – Iurii

0

Aggiungere il @JsonManagedReference Nella parte anteriore del rapporto (cioè User.java classe):

@Entity 
public class User implements Serializable { 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private long id; 

    @Column(name="name") 
    private String name; 

    @ManyToMany 
    @JoinTable(name="users_roles",[email protected](name = "user_fk"), [email protected](name = "role_fk")) 
    @JsonManagedReference 
    private Set<Role> roles = new HashSet<Role>(); 

    ... 

Aggiungere il @JsonBackReference Nella parte posteriore del rapporto (cioè classe Role.java):

@Entity 
public class Role implements Serializable { 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int id; 

    @ManyToMany(mappedBy="roles") 
    @JsonBackReference 
    private Set<User> users = new HashSet<User>(); 

    ... 

Questo funziona molto bene per me. :-)

Problemi correlati