user2831852
user2831852

Reputation: 605

Hibernate performs update and delete on custom JPQL

I am trying to update the fields of an entity that has a ManyToMany relationship, however, as I just want to update the table fields and ignore the ManyToMany relationship. The relationship is between the Company and UserSystem entities, it was defined in the relationship that company_user_system is the union table of the entities. The problem is that when executing my update in Company, always before my update, Hibernate makes an update in company and the relationship delete in user_system_company and this erases the relationship between Company and UserSystem and I don't understand why these two queries occur if I don't execut.

These are the queries, the first and second are not executed by my code:

Hibernate: update company set active=?, email=?, identification_code=?, trading_name=?, update_on=? where id=?
Hibernate: delete from company_user_system where company_id=?
Hibernate: update company set email=?, phone=?, corporate_name=?, trading_name=?, identification_code=?, email=?, phone2=? where id=?
Hibernate: select company0_.id as id1_0_, company0_.active as active2_0_, company0_.corporate_name as corporat3_0_, company0_.created_on as created_4_0_, company0_.email as email5_0_, company0_.email2 as email6_0_, company0_.identification_code as identifi7_0_, company0_.phone as phone8_0_, company0_.phone2 as phone9_0_, company0_.trading_name as trading10_0_, company0_.update_on as update_11_0_ from company company0_ where company0_.id=?

Following is the update implementation code:

public class CompanyRepositoryImpl implements CompanyRepositoryCustom {

    @PersistenceContext
    private EntityManager entityManager;


    public Company updateCompanyFields(Company company) {

        // ... fieldSql implementation omitted

        String sql = "UPDATE Company SET "+ fieldsSql +" WHERE id = :id ";

        Query query = entityManager.createQuery(sql);

        // set the values for the fields
        for (Method method : getMethods) {
            query.setParameter(lowercaseFirstCharInString(cutGetInMethods(method.getName())), method.invoke(company));
        }

        // set id
        query.setParameter("id", company.getId());

        // execute update and search the database to return the updated object
        if (query.executeUpdate() == 1) {

            query = entityManager.createQuery("SELECT c FROM Company c WHERE c.id = :id");

            query.setParameter("id", company.getId());

            Company getCompany = (Company) query.getResultList().get(0);

            return getCompany;
        }

        return null;
    }
    // ... Other methods omitted
}

Repository Code:

@Repository
public interface CompanyRepository extends JpaRepository<Company, Long>, JpaSpecificationExecutor<Company> , CompanyRepositoryCustom {

    @Modifying
    Company updateCompanyFields(Company company);
}

Company entity code, I just added the attributes that I think may contain something useful to try to solve the problem:

@Entity
@DynamicUpdate
@Table(name = "company")
public class Company implements Serializable {

    @CreationTimestamp
    @Column(name = "created_on", nullable = false)
    private Instant createdOn;

    @UpdateTimestamp
    @Column(name = "update_on")
    private Instant updateOn;

    @ManyToMany
    @JoinTable(
        name = "company_user_system",
        joinColumns = @JoinColumn(
            name = "company_id", referencedColumnName = "id"
        ),
        inverseJoinColumns = @JoinColumn(
            name = "user_system_id", referencedColumnName = "id"
        )
    )
    private Set<UserSystem> userSystems = new HashSet<>();
}

The UserSystem class defines the relationship as follows:

@ManyToMany(mappedBy = "userSystems")
private Set<Company> companies = new HashSet<>();

What may be causing this update and delete before my update?

Upvotes: 0

Views: 282

Answers (1)

Konstantin Triger
Konstantin Triger

Reputation: 1741

This happens because you changed somewhere the value(s) of your relationship. EntityManager tracks such changes and marks the entity as dirty. When you execute a custom SQL query Hibernate will perform all the pending queries (submit any dirty entities).

You may prevent it by calling EntityManager.clear().

Upvotes: 1

Related Questions