Hibernate mapping ManyToMany.



  • The database does not record linked audits in a table that would generate fields automatically. Here's the base code:

    CREATE TABLE place_type( 
      id bigserial NOT NULL,
      name character varying(255),
      file character varying(255),
      CONSTRAINT placetype_pkey PRIMARY KEY (id)
    );
    

    CREATE TABLE place (
    id bigserial NOT NULL,
    name character varying(255),
    file character varying(255),
    CONSTRAINT place_pkey PRIMARY KEY (id)
    );

    CREATE TABLE place_type_has_place (
    place_type_id bigserial NOT NULL,
    place_id bigserial NOT NULL,
    CONSTRAINT place_type_has_place_pkey PRIMARY KEY(place_type_id, place_id),
    CONSTRAINT place_type_has_place_fkey FOREIGN KEY(place_id)
    REFERENCES place(id),
    CONSTRAINT place_type_has_place_type_fkey FOREIGN KEY(place_type_id)
    REFERENCES place_type(id)
    );

    It's entites themselves:

    @Entity
    @Table(name="place_type")
    public class PlaceType {

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

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

    @JoinColumn(name="file")
    private String file;

    @ManyToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinTable(
    name="place_type_has_place",
    joinColumns = {@JoinColumn(name = "place_type_id")},
    inverseJoinColumns = {@JoinColumn(name = "place_id")}
    )
    private Set<Place> places = new HashSet<Place>();
    // getter setter
    }

    Entity Place:

    @Entity
    @Table
    public class Place {

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

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

    @JoinColumn(name="file")
    private String file;

    @ManyToMany(mappedBy="places", fetch=FetchType.EAGER)
    private Set<PlaceType> placeTypes = new HashSet<PlaceType>();

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(
    name="place_has_menu",
    joinColumns = {@JoinColumn(name = "place_id")},
    inverseJoinColumns = {@JoinColumn(name = "menu_id")}
    )
    private Set<Menu> menus = new HashSet<Menu>();
    //getters setters
    }

    The controller is processing the addition of a new phthiti Place to the base, which will result in the table place_type_has_place to add a recording from the aide of the new play and its plays.
    The new play is added to the base and the table place_type_has_place remains empty.

    @RequestMapping(value = "/savePlace", method = RequestMethod.POST)
    public String savePlace(PlaceForm placeForm, HttpServletRequest request,HttpServletResponse response, BindingResult result)
    throws ServletRequestBindingException, IOException {

    MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
    MultipartFile multipartFile = multipartRequest.getFile("file");
    
    System.out.println(placeForm.getPlaceType());
    Place place = new Place();
    
    place.setName(placeForm.getName());
    
    place.setFile(fileService.saveFile(multipartFile, "place"));
    
    Set&lt;PlaceType&gt; placeTypes = new HashSet&lt;PlaceType&gt;();
    PlaceType placeType = placeTypeService.getPlaceTypeById(placeForm.getPlaceType());
    placeTypes.add(placeType);
    place.setPlaceTypes(placeTypes);
    
    placeService.addPlace(place);
    
    return "redirect:addPlace";
    

    }

    With JSP, everything and everything in the cotroller is right. No zeros, etc. But no matter what you've done, it doesn't want to add aide to the contact table.



  • I'm not sure why it doesn't work, but it's embarrassing a couple of things in your example.

    (1) Isn't that how many, many, many people are treated in two ways?
    One side is supposed to be the owner of a relationship, another to use a mappedBy.

    (2) You're only in one direction. place.setPlaceTypes(placeTypes)
    And according to JPA rules (the annotated vessel is used by JPA) shall be installed in both.
    I mean. Each placeType of placeTypes must be implemented. placeType.getPlaces().add(place)

    (3) Maybe instead of:

    Set<PlaceType> placeTypes = new HashSet<PlaceType>();
    PlaceType placeType = placeTypeService.getPlaceTypeById(placeForm.getPlaceType());
    placeTypes.add(placeType);
    place.setPlaceTypes(placeTypes);
    

    It's better to do.

    PlaceType placeType = placeTypeService.getPlaceTypeById(placeForm.getPlaceType());
    place.getPlaceTypes().add(placeType);
    

    It's certainly not a mistake (at least in this case), but an extra job for yourself.

    App 2 and 3. Must be like this:

    PlaceType placeType = placeTypeService.getPlaceTypeById(placeForm.getPlaceType());
    // установка отношения в прямом направлении
    place.getPlaceTypes().add(placeType);
    // установка отношения в обратном направлении
    placeType.getPlaces().add(place);
    

    I think there's a reason to do two. Because the placeType has no place-to-place attitude, and it's reversal of a straight-up place.placeType.
    The installation in the straight direction creates a recording. "The installation" in the back immediately removes.
    Combined with paragraph 1. If I'm not mistaken, correctly installing a relationship in both directions, when you're looking like you're gonna get two footage in the joint table instead of one.




Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2