[ https://issues.apache.org/jira/browse/OLINGO-1522?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17311294#comment-17311294 ]
Vladislav Babin commented on OLINGO-1522: ----------------------------------------- My best guess so far is that olingo does not check or use the *uniqueConstraints* attribute of a @JoinTable annotation. When it comes to storing new links *JPALink::linkJPAEntities* is quite basic: {code:java} case MANY: Method getMethod = entityParser.getAccessModifier(sourceJPAEntity.getClass(), navigationProperty, JPAEntityParser.ACCESS_MODIFIER_GET); Collection<Object> relatedEntities = (Collection<Object>) getMethod.invoke(sourceJPAEntity); if (relatedEntities == null) { throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.ERROR_JPQL_CREATE_REQUEST, null); } relatedEntities.addAll(targetJPAEntities); setMethod.invoke(sourceJPAEntity, relatedEntities); break; {code} In my case the fix is to override the *User::setRoles* method: {code:java} public void setRoles(List<Role> roles) { if (roles == null) { this.roles = null; } else { List<Role> uniqueRoles = roles .stream() .filter(distinctByKey(p -> p.getId())) .collect(Collectors.toList()); this.roles = uniqueRoles; } } {code} Yet I think that olingo-jpa would benefit if the code was modified to to check *uniqueConstraints* > @JoinTable links are not updated correctly > ------------------------------------------ > > Key: OLINGO-1522 > URL: https://issues.apache.org/jira/browse/OLINGO-1522 > Project: Olingo > Issue Type: Bug > Components: odata2-jpa > Affects Versions: V2 2.0.11 > Reporter: Vladislav Babin > Priority: Major > > I have a classic setup of users, roles and user_roles table. Users are > defined as follows: > > {code:java} > @Entity > @Table(name = "users") > public class User implements Serializable { > ... > @Getter > @Setter > @ManyToMany(cascade = {CascadeType.ALL}) > @JoinTable(name = "user_roles", > joinColumns = @JoinColumn(name = "user_id"), > inverseJoinColumns = @JoinColumn(name = "role_id"), > uniqueConstraints = {@UniqueConstraint(columnNames = {"user_id", > "role_id"})} > ) > Role.class) > private List<Role> roles; > ... > }{code} > The problem is when I execute PATCH (PUT, MERGE) on Users endpoint > {code:java} > PATCH http://localhost:8080/admin/rest/odata/Users(7) > { > "RoleDetails":[ > { > "__metadata":{ > "id":"http://localhost:8080/admin/rest/Roles(3L)", > "uri":"http://localhost:8080/admin/rest/Roles(3L)", > "type":"default.Role" > }, > "Code":"ROLE8", > "Id":"3", > "Name":"Role 8" > } > ] > } > {code} > and the user has a role from the RoleDetails list then I get an error that > results from PostgreSQL's > {code:java} > ERROR: duplicate key value violates unique constraint "pk_user_roles" > {code} > At the same time when I update as user with plain JPA repository it succeeds: > {code:java} > @PUT > @Path("/{id}") > @Produces("application/json") > public User put(@Context SecurityContext securityContext, > @PathParam("id") Long id, User user){ > return userRepository.saveAndFlush(user); > } > {code} > Adding @EdmNavigationProperty to roles field did not help: > {code:java} > @Getter > @Setter > @ManyToMany(cascade = {CascadeType.ALL}) > @JoinTable(name = "user_roles", > joinColumns = @JoinColumn(name = "user_id"), > inverseJoinColumns = @JoinColumn(name = "role_id") > ) > @EdmNavigationProperty(toMultiplicity = Multiplicity.MANY, toType = > Role.class) > private List<Role> roles; > {code} > OData app uses Spring Boot entity manager as proposed in this tutorial: > [https://www.baeldung.com/odata] > The question is: shoudn't olingo check for existing records in a join table? > how can I further investigate the issue? Any working example of olingo2 + JPA > + @JoinTable would be highly appreciated. > > -- This message was sent by Atlassian Jira (v8.3.4#803005)