-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added a metadata table - one-to-many relationship enhanced #83
Added a metadata table - one-to-many relationship enhanced #83
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with the Database design which looks good.
I offered some possible improvement that could be done here or in a subsequent PR.
src/main/java/uk/ac/ebi/eva/evaseqcol/entities/SeqColMetadataEntity.java
Outdated
Show resolved
Hide resolved
import org.springframework.stereotype.Repository; | ||
|
||
import uk.ac.ebi.eva.evaseqcol.entities.SeqColLevelOneEntity; | ||
import uk.ac.ebi.eva.evaseqcol.entities.SeqColMetadataEntity; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not being used in this class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/main/java/uk/ac/ebi/eva/evaseqcol/service/SeqColLevelOneService.java
Outdated
Show resolved
Hide resolved
@@ -208,4 +215,28 @@ public List<SeqColExtendedDataEntity<List<Integer>>> constructIntegerListExtData | |||
return integerListExtendedDataEntities; | |||
} | |||
|
|||
public List<SeqColMetadataEntity> metadataObjectArrayListToMetadataList(List<Object[]> metadataArray) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this method need to be public ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not necessarily, it can be private in our case. However I'm not sure if we might need to used it outside of this class in the future.
@@ -83,6 +83,13 @@ public ResponseEntity<?> getSeqColByDigestAndLevel( | |||
return new ResponseEntity<>(HttpStatus.NOT_FOUND); | |||
} | |||
|
|||
@GetMapping(value = "/collection/{digest}/metadata") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand the rational for making the metadata available for a given digest and we could keep it for now.
However I think the metadata should injected in the SeqCol level2 to and be added with their own properties.
{
"sequences": [...],
"names": : [...],
"length": : [...],
"naming_convention": GENBANK,
"source_id": "GCA_000001",
"source_url": "https://..."
"ingested_on": 2024-04-21T12:00:00
}
This could be added to SeqColService.getSeqColByDigestAndLevel
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could also be added on request via a path variable - e.g. /collection/{digest}?level=2&metadata=true
- in case anyone wants the "plain" level 2 object?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could also be added on request via a path variable - e.g.
/collection/{digest}?level=2&metadata=true
- in case anyone wants the "plain" level 2 object?
I think that's a very good idea, it preserves the endpoint specified/required by the spec, and extend it with other optional parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think using ElementCollection
seems reasonable here - if I understand correctly, we can query based on metadata fields (i.e. "give me all the seqcols ingested after X date"), but metadata rows can't be created without a corresponding seqcol and will be automatically deleted if we remove its corresponding seqcol (both of which make sense). And the code is simplified which is always good.
The new seqcol_md table will remain almost the same, but without a primary key , only digest as a foreign key.
Is there still a requirement that the combination of all fields is unique? Based on this paragraph. I think this is what we want, just wanted to clarify.
src/main/java/uk/ac/ebi/eva/evaseqcol/controller/seqcol/SeqColController.java
Outdated
Show resolved
Hide resolved
@@ -83,6 +83,13 @@ public ResponseEntity<?> getSeqColByDigestAndLevel( | |||
return new ResponseEntity<>(HttpStatus.NOT_FOUND); | |||
} | |||
|
|||
@GetMapping(value = "/collection/{digest}/metadata") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could also be added on request via a path variable - e.g. /collection/{digest}?level=2&metadata=true
- in case anyone wants the "plain" level 2 object?
|
||
public List<SeqColMetadataEntity> getAllMetadata() { | ||
List<Object[]> metadataArrayList = repository.findAllMetadata(); | ||
return metadataObjectArrayListToMetadataList(metadataArrayList); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it worth using something like TupleTransformer in the repository to do this? I'm not sure how much difference it makes in practice compared to your conversion method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've a made a little enhancement in the transformation of the fetched md objects using streams (commit), however using TupleTransformer
might be a little bit tricky and require some changes in the design.
This is an example I found online that uses the TupleTransformer
:
List<PostRecord> postRecords = entityManager.createQuery("""
select
p.id,
p.title,
p.createdOn,
p.createdBy,
p.updatedOn,
p.updatedBy
from Post p
order by p.id
""")
.unwrap(org.hibernate.query.Query.class)
.setTupleTransformer(
(tuple, aliases) -> {
int i =0;
return new PostRecord(
longValue(tuple[i++]),
stringValue(tuple[i++]),
new AuditRecord(
localDateTimeValue(tuple[i++]),
stringValue(tuple[i++]),
localDateTimeValue(tuple[i++]),
stringValue(tuple[i++])
)
);
}
)
.getResultList();
Since we're using an interface repository, implementing this logic might require adding an additional repository class that will execute the custom query.
Not sure if that's gonna make the design more complex or not...
Idk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, your implementation is pretty neat so let's keep it like that 👍
…Controller.java Co-authored-by: April Shen <[email protected]>
…to List<MetadataEntity>
…path variable, into a request param within the getSeqcolByDigest endpoint
Description
closes #13
This PR has almost the same logic as the one-to-many relationship approach (PR #82), however with a different approach.
Changes
Java
We'll be using a new Java model using the
@ElementCollection
,@CollectionTable
in theSeqcolLevelOneEntity
:I think this will reduce the complexity of using
@One-to-many
relationship and managing different entities.See more in this article.
Data model
The new
seqcol_md
table will remain almost the same, but without a primary key , onlydigest
as a foreign key. This will allow for multiple entries with same digest (and eventually the other attributes):(
Timestamp
is still not working for some reason, we can debug it later).Endpoints
We added a new endpoint for the metadata:
/eva/webservices/seqcol/collection/{digest}/metadata
, which will return the following result.I would like to hear your feedback about this approach, and about the different techniques, logic, and data structures used.