Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/main/java/org/icatproject/core/entity/Investigation.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public class Investigation extends EntityBaseBean implements Serializable {
private Date releaseDate;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "investigation")
private List<Sample> samples = new ArrayList<>();
private List<InvestigationSample> samples = new ArrayList<>();

@OneToMany(cascade = CascadeType.ALL, mappedBy = "investigation")
private List<Shift> shifts = new ArrayList<>();
Expand Down Expand Up @@ -145,7 +145,7 @@ public Date getReleaseDate() {
return this.releaseDate;
}

public List<Sample> getSamples() {
public List<InvestigationSample> getSamples() {
return samples;
}

Expand Down Expand Up @@ -225,7 +225,7 @@ public void setReleaseDate(Date releaseDate) {
this.releaseDate = releaseDate;
}

public void setSamples(List<Sample> samples) {
public void setSamples(List<InvestigationSample> samples) {
this.samples = samples;
}

Expand Down
41 changes: 41 additions & 0 deletions src/main/java/org/icatproject/core/entity/InvestigationSample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.icatproject.core.entity;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

@Comment("Represents a many-to-many relationship between an investigation and a sample that has been used in that investigation")
@SuppressWarnings("serial")
@Entity
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "INVESTIGATION_ID", "SAMPLE_ID" }) })
public class InvestigationSample extends EntityBaseBean implements Serializable {

@JoinColumn(nullable = false, name = "INVESTIGATION_ID")
@ManyToOne(fetch = FetchType.LAZY)
private Investigation investigation;

@JoinColumn(nullable = false, name = "SAMPLE_ID")
@ManyToOne(fetch = FetchType.LAZY)
private Sample sample;

public Investigation getInvestigation() {
return this.investigation;
}

public Sample getSample() {
return this.sample;
}

public void setInvestigation(Investigation investigation) {
this.investigation = investigation;
}

public void setSample(Sample sample) {
this.sample = sample;
}
}
23 changes: 11 additions & 12 deletions src/main/java/org/icatproject/core/entity/Sample.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,23 @@

import org.icatproject.core.manager.LuceneApi;

@Comment("A sample to be used in an investigation")
@Comment("A sample to be used in one or more investigations")
@SuppressWarnings("serial")
@Entity
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "INVESTIGATION_ID", "NAME" }) })
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "PID" }) })
public class Sample extends EntityBaseBean implements Serializable {

@Comment("A persistent identifier attributed to this sample")
@Column(nullable = false, name = "PID")
private String pid;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "sample")
private List<Dataset> datasets = new ArrayList<>();

@JoinColumn(nullable = false, name = "INVESTIGATION_ID")
@ManyToOne(fetch = FetchType.LAZY)
private Investigation investigation;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "sample")
private List<InvestigationSample> investigationSamples = new ArrayList<>();

@Column(nullable = false, name = "NAME")
@Column(nullable = false)
private String name;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "sample")
Expand All @@ -59,8 +59,8 @@ public List<Dataset> getDatasets() {
return this.datasets;
}

public Investigation getInvestigation() {
return this.investigation;
public List<InvestigationSample> getInvestigationSamples() {
return this.investigationSamples;
}

public String getName() {
Expand All @@ -75,8 +75,8 @@ public void setDatasets(List<Dataset> datasets) {
this.datasets = datasets;
}

public void setInvestigation(Investigation investigation) {
this.investigation = investigation;
public void setInvestigationSamples(List<InvestigationSample> investigationSamples) {
this.investigationSamples = investigationSamples;
}

public void setName(String name) {
Expand All @@ -97,11 +97,10 @@ public void setType(SampleType type) {

@Override
public void getDoc(JsonGenerator gen) {
StringBuilder sb = new StringBuilder(name);
StringBuilder sb = new StringBuilder(pid + " " + name);
if (type != null) {
sb.append(" " + type.getName());
}
LuceneApi.encodeTextfield(gen, "text", sb.toString());
LuceneApi.encodeSortedDocValuesField(gen, "investigation", investigation.id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import org.icatproject.core.entity.InvestigationGroup;
import org.icatproject.core.entity.InvestigationInstrument;
import org.icatproject.core.entity.InvestigationParameter;
import org.icatproject.core.entity.InvestigationSample;
import org.icatproject.core.entity.InvestigationType;
import org.icatproject.core.entity.InvestigationUser;
import org.icatproject.core.entity.Job;
Expand Down Expand Up @@ -199,8 +200,8 @@ public String toString() {
DataCollectionDatafile.class, DataCollectionDataset.class, DataCollectionParameter.class,
DatafileParameter.class, DatasetParameter.class, InvestigationParameter.class, Job.class, Keyword.class,
PermissibleStringValue.class, Publication.class, RelatedDatafile.class, SampleParameter.class, Shift.class,
Study.class, InvestigationUser.class, InvestigationGroup.class, StudyInvestigation.class,
InvestigationInstrument.class, InstrumentScientist.class);
Study.class, InvestigationUser.class, InvestigationGroup.class, InvestigationSample.class,
StudyInvestigation.class, InvestigationInstrument.class, InstrumentScientist.class);
private static Set<String> entityNames = new HashSet<>();

private static String[] systemAttributes = { "createId", "createTime", "modId", "modTime" };
Expand Down
69 changes: 69 additions & 0 deletions src/main/scripts/upgrade_mysql_5_0.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
CREATE TABLE INVESTIGATIONSAMPLE (
ID BIGINT NOT NULL AUTO_INCREMENT,
CREATE_ID VARCHAR(255) NOT NULL,
CREATE_TIME DATETIME NOT NULL,
MOD_ID VARCHAR(255) NOT NULL,
MOD_TIME DATETIME NOT NULL,
INVESTIGATION_ID BIGINT NOT NULL,
SAMPLE_ID BIGINT NOT NULL,
PRIMARY KEY (ID)
);

ALTER TABLE INVESTIGATIONSAMPLE ADD CONSTRAINT FK_INVESTIGATIONSAMPLE_INVESTIGATION_ID FOREIGN KEY (INVESTIGATION_ID) REFERENCES INVESTIGATION (ID);
ALTER TABLE INVESTIGATIONSAMPLE ADD CONSTRAINT FK_INVESTIGATIONSAMPLE_SAMPLE_ID FOREIGN KEY (SAMPLE_ID) REFERENCES SAMPLE (ID);
ALTER TABLE INVESTIGATIONSAMPLE ADD CONSTRAINT UNQ_INVESTIGATIONSAMPLE_0 UNIQUE (INVESTIGATION_ID, SAMPLE_ID);

-- Set the PID field of existing Samples

DELIMITER //

CREATE PROCEDURE SET_SAMPLES_PID()
BEGIN
UPDATE SAMPLE SET PID = CONCAT('local:', LPAD(ID, 8, '0')) WHERE PID IS NULL;
END; //

DELIMITER ;

CALL SET_SAMPLES_PID();

DROP PROCEDURE SET_SAMPLES_PID;

-- Move existing Sample/Investigation relations over to the new table

DELIMITER //

CREATE PROCEDURE MOVE_SAMPLE_INVESTIGATION_RELATIONS()
BEGIN
DECLARE done BOOLEAN DEFAULT FALSE;
DECLARE _createid VARCHAR(255);
DECLARE _modid VARCHAR(255);
DECLARE _invid BIGINT;
DECLARE _id BIGINT;
DECLARE cur CURSOR FOR SELECT CREATE_ID, MOD_ID, INVESTIGATION_ID, ID FROM SAMPLE;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;

OPEN cur;
sampleLoop: LOOP
FETCH cur INTO _createid, _modid, _invid, _id;
IF done THEN
LEAVE sampleLoop;
END IF;

INSERT INTO INVESTIGATIONSAMPLE (CREATE_ID, CREATE_TIME, MOD_ID, MOD_TIME, INVESTIGATION_ID, SAMPLE_ID) VALUES (_createid, NOW(), _modid, NOW(), _invid, _id);
END LOOP sampleLoop;
CLOSE cur;
END; //

DELIMITER ;

CALL MOVE_SAMPLE_INVESTIGATION_RELATIONS();

DROP PROCEDURE MOVE_SAMPLE_INVESTIGATION_RELATIONS;

-- Alter the Sample table

ALTER TABLE SAMPLE MODIFY PID VARCHAR(255) NOT NULL;
ALTER TABLE SAMPLE DROP CONSTRAINT FK_SAMPLE_INVESTIGATION_ID;
ALTER TABLE SAMPLE DROP CONSTRAINT UNQ_SAMPLE_0;
ALTER TABLE SAMPLE ADD CONSTRAINT UNQ_SAMPLE_0 UNIQUE (PID);
ALTER TABLE SAMPLE DROP COLUMN INVESTIGATION_ID;
57 changes: 57 additions & 0 deletions src/main/scripts/upgrade_oracle_5_0.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
CREATE TABLE INVESTIGATIONSAMPLE (
ID NUMBER(19) NOT NULL,
CREATE_ID VARCHAR2(255) NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL,
MOD_ID VARCHAR2(255) NOT NULL,
MOD_TIME TIMESTAMP NOT NULL,
INVESTIGATION_ID NUMBER(19) NOT NULL,
SAMPLE_ID NUMBER(19) NOT NULL,
PRIMARY KEY (ID)
);

ALTER TABLE INVESTIGATIONSAMPLE ADD CONSTRAINT FK_INVESTIGATIONSAMPLE_INVESTIGATION_ID FOREIGN KEY (INVESTIGATION_ID) REFERENCES INVESTIGATION (ID);
ALTER TABLE INVESTIGATIONSAMPLE ADD CONSTRAINT FK_INVESTIGATIONSAMPLE_SAMPLE_ID FOREIGN KEY (SAMPLE_ID) REFERENCES SAMPLE (ID);
ALTER TABLE INVESTIGATIONSAMPLE ADD CONSTRAINT UNQ_INVESTIGATIONSAMPLE_0 UNIQUE (INVESTIGATION_ID, SAMPLE_ID);

-- Set the PID field of existing Samples

CREATE PROCEDURE SET_SAMPLES_PID AS
BEGIN
UPDATE SAMPLE SET PID = 'local:' || LPAD(ID, 8, '0') WHERE PID IS NULL;
END;
/

BEGIN
SET_SAMPLES_PID;
END;
/

DROP PROCEDURE SET_SAMPLES_PID;

-- Move existing Sample/Investigation relations over to the new table

CREATE PROCEDURE MOVE_SAMPLE_INVESTIGATION_RELATIONS AS
CURSOR CUR IS SELECT CREATE_ID, MOD_ID, INVESTIGATION_ID, ID FROM SAMPLE;
BEGIN
FOR CUR_SAMPLE in CUR LOOP
INSERT INTO INVESTIGATIONSAMPLE (CREATE_ID, CREATE_TIME, MOD_ID, MOD_TIME, INVESTIGATION_ID, SAMPLE_ID) VALUES (CUR_SAMPLE.CREATE_ID, CURRENT_TIMESTAMP, CUR_SAMPLE.MOD_ID, CURRENT_TIMESTAMP, CUR_SAMPLE.INVESTIGATION_ID, CUR_SAMPLE.ID);
END LOOP;
END;
/

BEGIN
MOVE_SAMPLE_INVESTIGATION_RELATIONS;
END;
/

DROP PROCEDURE MOVE_SAMPLE_INVESTIGATION_RELATIONS;

-- Alter the Sample table

ALTER TABLE SAMPLE MODIFY (PID NOT NULL);
ALTER TABLE SAMPLE DROP CONSTRAINT FK_SAMPLE_INVESTIGATION_ID;
ALTER TABLE SAMPLE DROP CONSTRAINT UNQ_SAMPLE_0;
ALTER TABLE SAMPLE ADD CONSTRAINT UNQ_SAMPLE_0 UNIQUE (PID);
ALTER TABLE SAMPLE DROP COLUMN INVESTIGATION_ID;

exit
7 changes: 7 additions & 0 deletions src/site/xhtml/release-notes.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@

<h1>ICAT Server Release Notes</h1>

<h2>5.0.0</h2>
<p>Make additions to the schema</p>
<ul>
<li>Make the relationship between Sample and Investigation many-to-many
(Issue 231).</li>
</ul>

<h2>4.10.0</h2>
<p>Make some additions to the schema</p>
<ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ public void testExportHeaders() throws Exception {
eiHandler.getExportHeader(Investigation.class));
assertEquals(
"Dataset(complete:0,description:1,doi:2,endDate:3,investigation(facility(name:4),"
+ "name:5,visitId:6),location:7,name:8,sample(investigation(facility(name:9),"
+ "name:10,visitId:11),name:12),startDate:13,type(facility(name:14),name:15))",
+ "name:5,visitId:6),location:7,name:8,sample(pid:9),startDate:10,type(facility(name:11),name:12))",
eiHandler.getExportHeader(Dataset.class));
assertEquals("DataCollection(?:0,doi:1)", eiHandler.getExportHeader(DataCollection.class));
assertEquals(
Expand Down Expand Up @@ -116,8 +115,7 @@ public void testExportHeaderAll() throws Exception {
"Dataset(createId:0,createTime:1,modId:2,modTime:3,"
+ "complete:4,description:5,doi:6,endDate:7,investigation(facility(name:8),"
+ "name:9,visitId:10),location:11,name:12,"
+ "sample(investigation(facility(name:13),name:14,visitId:15),"
+ "name:16),startDate:17,type(facility(name:18),name:19))",
+ "sample(pid:13),startDate:14,type(facility(name:15),name:16))",
eiHandler.getExportHeaderAll(Dataset.class));
assertEquals("DataCollection(?:0,createId:1,createTime:2,modId:3,modTime:4,doi:5)",
eiHandler.getExportHeaderAll(DataCollection.class));
Expand Down Expand Up @@ -240,7 +238,7 @@ public void testFieldByName() throws Exception {
public void testRels() throws Exception {

testRel(Investigation.class, "From Investigation to Keyword by keywords many setInvestigation",
"From Investigation to Sample by samples many setInvestigation",
"From Investigation to InvestigationSample by samples many setInvestigation",
"From Investigation to StudyInvestigation by studyInvestigations many setInvestigation",
"From Investigation to Shift by shifts many setInvestigation",
"From Investigation to Dataset by datasets many setInvestigation",
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/org/icatproject/integration/TestWS.java
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ public void publicStep() throws Exception {
@Test
public void entities() throws Exception {
List<String> entities = session.getEntityNames();
assertEquals(38, entities.size());
assertEquals(39, entities.size());
assertTrue(entities.contains("Application"));
}

Expand Down