Поле 'fieldName' не имеет значения по умолчанию в отношении ManyToMany - PullRequest
0 голосов
/ 26 апреля 2020

У меня есть следующие объекты, которые находятся в отношении ManyToMany.

UpdateKeyEntity.java

@Embeddable
public class UpdateKeyEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name = "product_name")
    private String productName;
    @Column(name = "product_base_version")
    private String productBaseVersion;
    @Column(name = "update_level")
    private int updateLevel;
    @Column(name = "channel")
    private String channel;

   public UpdateKeyEntity() {

    }

    public UpdateKeyEntity(String productName, String productBaseVersion, int updateLevel, String channel) {

        this.productName = productName;
        this.productBaseVersion = productBaseVersion;
        this.updateLevel = updateLevel;
        this.channel = channel;
    }

    @Override
    public int hashCode() {

        return Objects.hash(this.productName, this.productBaseVersion, this.channel, this.updateLevel);
    }

    @Override
    public boolean equals(Object obj) {

        if (obj == this) {
            return true;
        }
        if (obj instanceof UpdateKeyEntity) {
            UpdateKeyEntity updateKeyEntity = (UpdateKeyEntity) obj;
            return this.productName.equals(updateKeyEntity.getProductName()) && this.productBaseVersion.equals(
                    updateKeyEntity.getProductBaseVersion()) && this.channel.equals(updateKeyEntity.getChannel()) &&
                    this.updateLevel == updateKeyEntity.updateLevel;
        }
        return false;
    }

}

UpdateEntity.java

@Entity
@Table(name = Constants.TABLE_NAME)
public class UpdateEntity {

    @EmbeddedId
    private UpdateKeyEntity updateKeyEntity;
    @Column(name = "files_added", columnDefinition = "TEXT")
    private String filesAdded;
    @Column(name = "files_modified", columnDefinition = "TEXT")
    private String filesModified;
    @Column(name = "files_removed", columnDefinition = "TEXT")
    private String filesRemoved;
    @Column(name = "lifecycle_state")
    private String lifeCycleState;
    @ManyToMany(
            cascade = {CascadeType.MERGE, CascadeType.PERSIST}
    )
    @JoinTable(
            name = "update_level_security_advisories",
            joinColumns = {
                    @JoinColumn(name = "product_name", referencedColumnName = "product_name"),
                    @JoinColumn(name = "product_base_version", referencedColumnName = "product_base_version"),
                    @JoinColumn(name = "update_level", referencedColumnName = "update_level"),
                    @JoinColumn(name = "channel", referencedColumnName = "channel")
            },
            inverseJoinColumns = @JoinColumn(name = "sec_ad_id", referencedColumnName = "id")
    )
    private Set<SecurityAdvisoryEntity> securityAdvisoryEntityList = new HashSet<>();

    public UpdateEntity() {

    }

    public UpdateEntity(UpdateLevelDescription updateLevelDescription) {

        this.updateKeyEntity = new UpdateKeyEntity(updateLevelDescription.getProductName(),
                updateLevelDescription.getProductBaseVersion(), updateLevelDescription.getUpdateLevel(),
                updateLevelDescription.getChannel());
        this.filesAdded = updateLevelDescription.getFilesAdded();
        this.filesModified = updateLevelDescription.getFilesModified();
        this.filesRemoved = updateLevelDescription.getFilesRemoved();
        this.lifeCycleState = updateLevelDescription.getLifeCycleState();

        addSecAdd(updateLevelDescription.getSecurityAdvisoryEntitylist);
    }


    // getter and setters

    private void addSecAdd(List<SecurityAdvisoryEntity> securityAdvisoryEntitylist) {

        for (SecurityAdvisoryEntity securityAdvisoryEntity : securityAdvisoryEntitylist) {
            securityAdvisoryEntityList.add(securityAdvisoryEntity);
            securityAdvisoryEntity.getUpdateEntityList().add(this);
            }   
    }

    @Override
    public int hashCode() {

        return Objects.hash(this.updateKeyEntity.getProductBaseVersion(),
                this.updateKeyEntity.getChannel(), this.updateKeyEntity.getUpdateLevel(), this.filesAdded,
                this.filesModified, this.filesRemoved);
    }

    @Override
    public boolean equals(Object obj) {

        if (obj == this) {
            return true;
        }
        if (obj instanceof UpdateEntity) {
            UpdateEntity updateEntity = (UpdateEntity) obj;
                 return (updateEntity.getUpdateKeyEntity().getProductBaseVersion().equals(this.
                    getUpdateKeyEntity().getProductBaseVersion()) && updateEntity.getUpdateKeyEntity().getChannel().
                    equals(this.getUpdateKeyEntity().getChannel()) && updateEntity.getUpdateKeyEntity().getUpdateLevel()
                    == this.getUpdateKeyEntity().getUpdateLevel());
        }
        return false;
    }
}

SecurityAdvisoryEntity.java

@Entity
@Table(name = "security_advisories")
public class SecurityAdvisoryEntity {

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

    @ManyToMany(mappedBy = "securityAdvisoryEntityList")
    private List<UpdateEntity> updateEntityList = new ArrayList<>();

    @Column(name = "overview", columnDefinition = "TEXT")
    private String overview;

    @Column(name = "severity", columnDefinition = "TEXT")
    private String severity;

    @Column(name = "description", columnDefinition = "TEXT")
    private String description;

    @Column(name = "impact", columnDefinition = "TEXT")
    private String impact;

    @Column(name = "solution", columnDefinition = "TEXT")
    private String solution;

    @Column(name = "notes", columnDefinition = "TEXT")
    private String notes;

    @Column(name = "credits", columnDefinition = "TEXT")
    private String credits;

    public SecurityAdvisoryEntity(SecurityAdvisoryDescription securityAdvisoryDescription) {

        this.id = securityAdvisoryDescription.getId();
        this.overview = securityAdvisoryDescription.getOverview();
        this.severity = securityAdvisoryDescription.getSeverity();
        this.description = securityAdvisoryDescription.getDescription();
        this.impact = securityAdvisoryDescription.getImpact();
        this.solution = securityAdvisoryDescription.getSolution();
        this.notes = securityAdvisoryDescription.getNotes();
        this.credits = securityAdvisoryDescription.getCredits();
    }
    // getters and setters
}        

При выполнении следующего

public void persistUpdateLevelDescription(UpdateLevelDescription updateLevelDescription) throws UpdatesException {

    UpdateEntity updateEntity = new UpdateEntity(updateLevelDescription);
    EntityManager entityManager = getEntityManager();
    try {
        persistEntity(updateEntity, entityManager);
        }catch (UpdatesException e) {
                //log and throw
        }
}


private <T> void persistEntity(T entity, EntityManager entityManager) throws UpdatesException {

    int numOfAttempts = 0;
    do {
        numOfAttempts++;
        try {
            entityManager.getTransaction().begin();
            entityManager.persist(entity);
            entityManager.getTransaction().commit();
            return;
        } catch (PersistenceException persistenceException) {
            validatePersistenceException(persistenceException);
        }
    } while (numOfAttempts <= databaseConnection.getMaxRetries());
    throw new UpdatesException("Database connection failed when inserting the provided entity");
}

я получаю следующую ошибку,

2020-04-26 21:38:24 WARN  SqlExceptionHelper:129 - SQL Error: 1364, SQLState: HY000
2020-04-26 21:38:24 ERROR SqlExceptionHelper:131 - Field 'updateEntity_product_name' doesn't have a default value
2020-04-26 21:38:24 INFO  AbstractBatchImpl:193 - HHH000010: On release of batch it still contained JDBC statements
2020-04-26 21:38:24 ERROR ExceptionMapperStandardImpl:39 - HHH000346: Error during managed flush [org.hibernate.exception.GenericJDBCException: could not execute statement]
2020-04-26 21:38:24 ERROR UpdatesException:29 - Database connection failed when inserting 10 update level of wso2i2-5.7.0
org.kasun.updates.updatesms.exception.UpdatesException: Database connection failed when inserting 10 update level of wso2i2-5.7.0
    at org.kasun.updates.updatesms.dao.UpdatesRepository.persistUpdateLevelDescription(UpdatesRepository.java:337)
    at org.kasun.updates.updatesms.UpdatesManager.persistUpdateLevelDescriptions(UpdatesManager.java:142)
    at org.kasun.updates.updatesms.service.UpdatesService.updateInformation(UpdatesService.java:227)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.wso2.msf4j.internal.router.HttpMethodInfo.invokeResource(HttpMethodInfo.java:187)
    at org.wso2.msf4j.internal.router.HttpMethodInfo.invoke(HttpMethodInfo.java:143)
    at org.wso2.msf4j.internal.MSF4JHttpConnectorListener.dispatchMethod(MSF4JHttpConnectorListener.java:218)
    at org.wso2.msf4j.internal.MSF4JHttpConnectorListener.lambda$onMessage$57(MSF4JHttpConnectorListener.java:129)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.kasun.updates.updatesms.exception.UpdatesException: Exception occurred while connecting to the database
    at org.kasun.updates.updatesms.dao.UpdatesRepository.validatePersistenceException(UpdatesRepository.java:740)
    at org.kasun.updates.updatesms.dao.UpdatesRepository.persistEntity(UpdatesRepository.java:451)
    at org.kasun.updates.updatesms.dao.UpdatesRepository.persistUpdateLevelDescription(UpdatesRepository.java:332)
    ... 13 more
Caused by: javax.persistence.RollbackException: Error while committing the transaction
    at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:75)
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:71)
    at org.kasun.updates.updatesms.dao.UpdatesRepository.persistEntity(UpdatesRepository.java:448)
    ... 14 more
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not execute statement
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:147)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155)
    at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:56)
    ... 16 more
Caused by: org.hibernate.exception.GenericJDBCException: could not execute statement
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:207)
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:45)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2934)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3434)
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:89)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:582)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:456)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1397)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:473)
    at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3133)
    at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2370)
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:467)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:146)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:220)
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:68)
    ... 15 more
Caused by: java.sql.SQLException: Field 'updateEntity_product_name' doesn't have a default value
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:998)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3847)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3783)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2447)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2594)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2545)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1901)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2113)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2049)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2034)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:147)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)
    ... 32 more

Что я делаю неправильно?

...