简体   繁体   中英

@ElementCollection setField throws SQLSyntaxErrorException: ORA-00942

I have 2 java classes, one of them contains the other as a list by @ElementCollection. When I try to set that list, following error occurs:

Local Exception Stack: 
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.1.3.v20110304-r9073): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist

Error Code: 942
Call: SELECT t0.VERSIONS FROM MainProcess_VERSIONS t0 WHERE (t0.MainProcess_SUBJECT_ID = ?)
bind => [#id]
Query: DirectReadQuery(name="versions" sql="SELECT t0.VERSIONS 
FROM MainProcess_VERSIONS t0 WHERE (t0.MainProcess_SUBJECT_ID = ?)")
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:683)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:526)
.
.
.
at ...Editor.MAINPROCESS._persistence_propertyChange(MAINPROCESS.java)
at ...Editor.MAINPROCESS._persistence_set_versions(MAINPROCESS.java)
at ...MAINPROCESS.setVersions(MAINPROCESS.java:79)
at ...DataModel.fillSubprocessSubject(DataModel.java:643)
at ...DataModel.load(DataModel.java:321)

If I remove the @ElementCollection then I get the following error

Error Code: 942
Call: 
SELECT t1.ACT_VERSION, t1.SUBJECT_ID, t1.ACT_VERSION_REMARK,
  t1.ACT_VALID_TO, t1.ACT_VERSION_ACCEPTED, t1.NORMALRETURNVALUES, t1.ACT_VALID_FROM 
FROM MAINPROCESS_MAINPROCESSVERSION t0, MAINPROCESSVERSION t1
WHERE ((t0.MainProcess_SUBJECT_ID = ?) AND ((t1.SUBJECT_ID = t0.SUBJECT_ID) 
AND (t1.ACT_VERSION = t0.ACT_VERSION)))
    bind => [#id]

Here are my classes,

MainProcess:

@Entity
public class MainProcess implements Serializable {

  @Id
  @Column(name = "SUBJECT_ID", nullable = false)
  private Long subjectId;
  
  ...other columns

  @ElementCollection
  private List<MainProcessVersion> versions = new ArrayList<MainProcessVersion>();

  public MainProcess() {
  }

  public void setVersions(List<MainProcessVersion> versions) {
    this.versions = versions;
  }

  public List<MainProcessVersion> getVersions() {
    return versions;
  }

  other getters and setters...
}

MainProcessVersion:

@Entity
@IdClass(MainProcessVersionPK.class)
public class MainProcessVersion implements Serializable {

  @Id
  @Column(name = "SUBJECT_ID", nullable = false)
  @XmlTransient
  private Long subjectId;

  @Id
  @Column(name = "ACT_VERSION")
  private Long actVersion;

  ...other columns

  private List<String> normalReturnValues;

  public MainProcessVersion() {
  }

  getters and setters...

}

And the function in which the error occurs:

private MainProcess fillSubprocessSubject(Long Id) {
    MainProcess p = someFacade.getProcess(Id);
    List<MainProcessVersion> versions = someFacade.getProcessVersions(Id);
    p.setVersions(versions); //error is here
    return p;
}

Thanks in advance for any help.

I managed to solve my problem. Most important was to understand the difference between @ElementCollection and @OneToMany annotation. I cannot better explain like this .

So the problem was that my MainProcessVersion.java was annotated with @Entity , thus I could not add the @ElementCollection annotation to it in the MainProcess.java .

 @ElementCollection //One cannot use this annotation because MainProcessVersion is an entity.
 private List<MainProcessVersion> versions = new ArrayList<MainProcessVersion>();

But I need the Entity, so I created resultRow class wich is the same as my Entity class except the annotation. After query selection, I cast my result to my new resultRow class and I can set that list in the MainProcess.java .

My resultRow class:

public class MainProcessVersionResultRow implements Serializable {
    
    private Long subjectId;
    ...other code
}

My old MainProcess class

 @Entity
public class MainProcess implements Serializable {

    @Id
    @Column(name = "SUBJECT_ID", nullable = false)
    private Long subjectId;

    ...other columns
    
    //without @ElementCollection and the new resultRow object type
    private List<MainProcessVersionResultRow> versions = new ArrayList<MainProcessVersionResultRow>();

    public MainProcess() {
    }

    ...getters. setters
}

And then, I "cast" my entity to resultRow class:

private MainProcess fillSubprocessSubject(Long subjectId) {
        MainProcess p =
            someFacade.getSubprocessSubject(subjectId);
        List<MainProcessVersion> versions = someFacade.getProcessVersions(subjectId);
        List<MainProcessVersionResultRow> versionResultRows = new ArrayList<MainProcessVersionResultRow>();

        for (MainProcessVersion vs : versions) {
            MainProcessVersionResultRow versionSingleResultRow = new MainProcessVersionResultRow(vs);
            versionSingleResultRow.setNormalReturnValues(processReturnValues(p.getSubjectId(), vs.getActVersion()));
            versionResultRows.add(versionSingleResultRow);
        }

        p.setVersions(versionResultRows); //does not throw an error any more
        return p;
    }

So conclusion : Do not use @ElementCollection on a class that has an @Entity annotation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM