I am practicing a example of my own using spring data jpa, hibernate and MySql.

how to make ManyToMany relationship on same object?

for example, a friend class can have many friends

So far i have done are,

user friend mapper table

CREATE TABLE if not exists `user_friends` (
`user_id` int(6) NOT NULL,
`frnd_id` int(6) NOT NULL,
PRIMARY KEY (`user_id`, `frnd_id`),
INDEX `FK_USER_FRNDS` (`frnd_id`),
CONSTRAINT `FK_USER` FOREIGN KEY (`user_id`) REFERENCES `personalDetails` (`user_id`),
CONSTRAINT `FK_USER_FRNDS` FOREIGN KEY (`frnd_id`) REFERENCES `personalDetails` (`user_id`)

);

PersonalDetails class

@Entity
@Table(name="personalDetails")
public class PersonalDetails implements Serializable{

    @Id 
    @GeneratedValue(generator="gen")
    @Column(name="user_id", unique=true)
    private Long id;

    @ManyToMany(cascade={CascadeType.ALL}, fetch= FetchType.LAZY)
    @JoinTable(name="user_friends",
    joinColumns={@JoinColumn(name="user_id")},
    inverseJoinColumns={@JoinColumn(name="frnd_id")})
    private Set<PersonalDetails> friends = new HashSet<PersonalDetails>();

    @ManyToMany(mappedBy="friends")
    private Set<PersonalDetails> friendsMapper;

        //getters and setters
}

and in my controller am calling PersonalDetails service class update method like this:

public String joinFriend(@PathVariable Long frndId, Principal principal) throws PersonalDetailsNotFound, UserNotFoundException{
    logger.info("Get came to /user/frnd/join.html");
    if(frndId!=null){
        logger.info("Going to add friend..");
        PersonalDetails persUser = userService.findByUsername(principal.getName()).getPersonalDetails();

        PersonalDetails pFrnd = userService.findById(frndId).getPersonalDetails();

        persUser.getFriends().add(pFrnd);

        personalDetailService.update(persUser);
    }

it's throwing this exception

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '19' for key 'PRIMARY'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4187)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4119)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133)
... 93 more

any help appreciated..

有帮助吗?

解决方案

Based on this error message, there is already an entry in the database with the same primary key:

MySQLIntegrityConstraintViolationException: Duplicate entry '19' for key 'PRIMARY'

Try to cleanup the database, or if you are using sequences to generate the id's, recreate the sequence so that it has a higher value than the maximum id on the table.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top