orphanRemoval被忽略了

时间:2016-12-19 22:38:03

标签: java jpa eclipselink

我正在使用EclipseLink,并且我与orphanRemoval = true注释的一方有一对多的关系。当我将“many”列表(quoteItems)设置为null并尝试合并后跟对父项的刷新(Quote,“one”insteance)时,JPA会尝试更新子项,将外键设置为null而不是删除这些孩子。这是代码:

“一”类

public class Quote implements NamedBean, Serializable {
.
.
.
    // bi-directional many-to-one association to QuoteItem
    @OneToMany(mappedBy = "quote", fetch = FetchType.EAGER, cascade = { CascadeType.MERGE, CascadeType.PERSIST }, orphanRemoval=true)
    @XmlElement
    public List<QuoteItem> getQuoteItems() {
        if ((quoteItems == null || quoteItems.size() == 0) && (quoteAsXml != null && quoteAsXml.length() > 0)) {
            // Reconstitute the quoteItems from the quoteAsXml
            QuoteDAO.unpackQuoteItems(this);
        }

        return this.quoteItems;
    }
.
.
.
}

“很多”课程:

public class QuoteItem implements Serializable {
.
.
.
    //bi-directional many-to-one association to Quote
    @ManyToOne
    @XmlTransient
    public Quote getQuote() {
        return this.quote;
    }

.
.
.
}

截断的堆栈转储:

.
.
.
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'quote_id' cannot be null
Error Code: 1048
Call: UPDATE quote_item SET QUOTE_ID = ? WHERE (ID = ?)
    bind => [null, 64]
Query: UpdateObjectQuery(com.millereads.model.quote.QuoteItem@11e6d13)
    at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:331)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:902)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:964)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:633)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:560)
    at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2055)
    at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:306)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.updateObject(DatasourceCallQueryMechanism.java:797)
    at org.eclipse.persistence.internal.queries.StatementQueryMechanism.updateObject(StatementQueryMechanism.java:435)
    at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.updateObjectForWriteWithChangeSet(DatabaseQueryMechanism.java:1078)
    at org.eclipse.persistence.queries.UpdateObjectQuery.executeCommitWithChangeSet(UpdateObjectQuery.java:84)
    at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:301)
    at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:904)
    at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:803)
    at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
    at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1857)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1839)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1790)
    at org.eclipse.persistence.internal.sessions.CommitManager.commitChangedObjectsForClassWithChangeSet(CommitManager.java:273)
    at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsForClassWithChangeSet(CommitManager.java:193)
    at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:139)
    at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:4263)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1441)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithPreBuiltChangeSet(UnitOfWorkImpl.java:1587)
    at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.writeChanges(RepeatableWriteUnitOfWork.java:455)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:874)
    ... 95 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'quote_id' cannot be null
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    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:1039)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2683)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2144)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2444)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2362)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2347)
    at com.sun.gjc.spi.base.PreparedStatementWrapper.executeUpdate(PreparedStatementWrapper.java:125)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:892)
    ... 124 more

持久性代码(目前情况相同,投诉相同)

    public Quote update(Quote entity) {
        if (entity.getState() == QuoteState.POIssued) {
            String quoteAsXml = entity.getQuoteAsXml();

            if (quoteAsXml == null || quoteAsXml.length() == 0) {
                // Convert the Quote into XML 
                try {
                    JAXBContext contextObj;

                    contextObj = JAXBContext.newInstance(Quote.class);
                    ByteArrayOutputStream outStream = new ByteArrayOutputStream();

                    Marshaller marshallerObj = contextObj.createMarshaller();  
                    marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);  

                    marshallerObj.marshal(entity, outStream);  
                    entity.setQuoteAsXml(outStream.toString());
                } catch (JAXBException e) {
                    throw new RuntimeException(e);
                }  
            }

            // Do not save the quoteItems!              
            entity.getQuoteItems().clear();
        }

        return super.update(entity);
    }

祖先类'update():

    @Override
    public T update(T entity) {
        T result =  manager.merge(entity);
        manager.flush();
        return result;
    }

0 个答案:

没有答案