Skip to content

Commit

Permalink
Add support for confounding variables (#877)
Browse files Browse the repository at this point in the history
* add todo to open PR

* add mermaid plot

* change to identifier

* add sequence diagrams

* update sql scripts

* Pass schema validation

* Fix order of statements

* do not allow null values for measurement counts

* refine diagram

* update sql so it only creates missing tables

* minimal example

* add javadoc

* wip

* add confounding variables to templates

* move the `@Transactional` aspect to the implementing class

> The Spring team recommends that you annotate methods of concrete classes with the @transactional annotation, rather than relying on annotated methods in interfaces, even if the latter does work for interface-based and target-class proxies as of 5.0.
https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/annotations.html

* wip

* wip

* wip

* Fix file size formatting

* Fix connection testing for openbis

* Add equals and hash code to Sample.java object

* implement the update case for confounding variables

* Implement sample/batch deletion

* extract methods for measurement and sample creation in openbis

* Fix merge breaks

* fix test

* update demo with detail box and cards

* static import of Objects.requireNonNull

* Add javadoc to HasBoundField.java

* Extract StringBean

* Add color and cursor classes

* replace random by cursor

* add missing flex-align-items-baseline

* Add ConfoundingVariablesUserInput

* Add info text and adjust gap

* Add tab for confounding variables

* update dev bundle

* show existing confounding variables

* add new confounding variables

* Implement editing of confounding variables

* Throw exception for duplicate columns

* Prevent creation and rename of duplicate confounding variable

* Prevent duplicate naming and accidental deletion

* prettify frontend

* Fix groups not being loaded

* remove file

* Address sonar cloud analysis of SampleRepositoryImpl.java

* address further sonarcloud issues

* Rename method

Co-authored-by: Sven F. <[email protected]>

* remove Propagation.REQUIRES_NEW

I don't think we need a new transaction when creating samples
Co-authored-by: Sven F. <[email protected]>

* Replace Map#foreach with Collectors#toMap

Co-authored-by: Sven F. <[email protected]>

* Ask before deleting confounding variables

Co-authored-by: Sven F. <[email protected]>

---------

Co-authored-by: KochTobi <[email protected]>
Co-authored-by: Sven F. <[email protected]>
  • Loading branch information
3 people authored Jan 28, 2025
1 parent 9addc37 commit 7042182
Show file tree
Hide file tree
Showing 58 changed files with 2,938 additions and 527 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import life.qbic.projectmanagement.domain.model.experiment.ExperimentId;
import life.qbic.projectmanagement.domain.model.sample.Sample;
import life.qbic.projectmanagement.domain.repository.BatchRepository;
import life.qbic.projectmanagement.infrastructure.sample.QbicSampleRepository;
import life.qbic.projectmanagement.infrastructure.sample.SampleJpaRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

Expand All @@ -31,11 +31,11 @@ public class BatchJpaRepository implements BatchRepository {
private static final Logger log = logger(BatchJpaRepository.class);

private final QbicBatchRepo qbicBatchRepo;
private final QbicSampleRepository qbicSampleRepository;
private final SampleJpaRepository qbicSampleRepository;

@Autowired
public BatchJpaRepository(QbicBatchRepo qbicBatchRepo,
QbicSampleRepository qbicSampleRepository) {
SampleJpaRepository qbicSampleRepository) {
this.qbicBatchRepo = qbicBatchRepo;
this.qbicSampleRepository = qbicSampleRepository;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package life.qbic.projectmanagement.infrastructure.confounding;

import java.util.Collection;
import java.util.List;
import life.qbic.projectmanagement.domain.model.confounding.jpa.ConfoundingVariableData;
import org.springframework.data.repository.ListCrudRepository;

public interface ConfoundingVariableJpaRepository extends
ListCrudRepository<ConfoundingVariableData, Long> {

long countByExperimentIdEquals(String experimentId);

List<ConfoundingVariableData> findAllByExperimentIdEquals(String experimentId);

boolean existsDistinctByIdIsIn(Collection<Long> ids);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package life.qbic.projectmanagement.infrastructure.confounding;

import java.util.List;
import java.util.Optional;
import life.qbic.projectmanagement.domain.model.confounding.jpa.ConfoundingVariableLevelData;
import org.springframework.data.repository.ListCrudRepository;

public interface ConfoundingVariableLevelJpaRepository extends
ListCrudRepository<ConfoundingVariableLevelData, Long> {

List<ConfoundingVariableLevelData> findAllBySampleIdEquals(String sampleId);

List<ConfoundingVariableLevelData> findAllByVariableIdEquals(long variableId);

List<ConfoundingVariableLevelData> findAllByVariableIdIn(List<Long> variableIds);

Optional<ConfoundingVariableLevelData> findBySampleIdEqualsAndVariableIdEquals(String sampleId,
long variableId);

long countByVariableIdEquals(long variableId);

void deleteAllByVariableIdEquals(long variableId);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package life.qbic.projectmanagement.infrastructure.confounding;

import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import life.qbic.projectmanagement.domain.model.confounding.jpa.ConfoundingVariableLevelData;
import life.qbic.projectmanagement.domain.repository.ConfoundingVariableLevelRepository;
import org.springframework.stereotype.Repository;

/**
* The implementation of the {@link ConfoundingVariableLevelRepository} interface.
* Delegates method calls to the corresponding JPA repositories.
* @since 1.6.0
*/
@Repository
public class ConfoundingVariableLevelRepositoryImpl implements ConfoundingVariableLevelRepository {

private final ConfoundingVariableLevelJpaRepository jpaRepository;

public ConfoundingVariableLevelRepositoryImpl(
ConfoundingVariableLevelJpaRepository jpaRepository) {
this.jpaRepository = jpaRepository;
}

@Override
public List<ConfoundingVariableLevelData> findAllForSample(String projectId, String sampleId) {
return jpaRepository.findAllBySampleIdEquals(sampleId);
}

@Override
public List<ConfoundingVariableLevelData> findAllForVariable(String projectId,
long variableId) {
return jpaRepository.findAllByVariableIdEquals(variableId);
}


@Override
public List<ConfoundingVariableLevelData> findAllForVariables(String projectId,
List<Long> variableIds) {
return jpaRepository.findAllByVariableIdIn(variableIds);
}

@Override
public Optional<ConfoundingVariableLevelData> findVariableLevelOfSample(String projectId,
String sampleId, long variableId) {
return jpaRepository.findBySampleIdEqualsAndVariableIdEquals(sampleId, variableId);
}


@Override
public <S extends ConfoundingVariableLevelData> S save(String projectId, S entity) {
return jpaRepository.save(entity);
}

@Override
public Optional<ConfoundingVariableLevelData> findById(String projectId, Long aLong) {
return jpaRepository.findById(aLong);
}

@Override
public long countLevelsOfVariable(String projectId, long variableId) {
return jpaRepository.countByVariableIdEquals(variableId);
}

@Override
public void deleteById(String projectId, Long aLong) {
jpaRepository.deleteById(aLong);
}

@Override
public void deleteAllForSample(String projectId, String sampleId) {
List<ConfoundingVariableLevelData> allBySampleIdEquals = jpaRepository.findAllBySampleIdEquals(
sampleId);
Set<Long> levelIds = allBySampleIdEquals.stream().map(ConfoundingVariableLevelData::getId)
.collect(Collectors.toSet());
jpaRepository.deleteAllById(levelIds);
}

@Override
public void deleteAllForVariable(String projectId, long variableId) {
jpaRepository.deleteAllByVariableIdEquals(variableId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package life.qbic.projectmanagement.infrastructure.confounding;

import java.util.Collection;
import java.util.List;
import java.util.Optional;
import life.qbic.projectmanagement.domain.model.confounding.jpa.ConfoundingVariableData;
import life.qbic.projectmanagement.domain.repository.ConfoundingVariableRepository;
import org.springframework.stereotype.Repository;

/**
* The implementation of the {@link ConfoundingVariableRepository} interface.
* Delegates method calls to the corresponding JPA repositories.
* @since 1.6.0
*/
@Repository
public class ConfoundingVariableRepositoryImpl implements ConfoundingVariableRepository {

private final ConfoundingVariableJpaRepository jpaRepository;

public ConfoundingVariableRepositoryImpl(ConfoundingVariableJpaRepository jpaRepository) {
this.jpaRepository = jpaRepository;
}

@Override
public <S extends ConfoundingVariableData> List<S> saveAll(String projectId,
Iterable<S> entities) {
return jpaRepository.saveAll(entities);
}

@Override
public List<ConfoundingVariableData> findAll(String projectId, String experimentId) {
return jpaRepository.findAllByExperimentIdEquals(experimentId);
}

@Override
public List<ConfoundingVariableData> findAllById(String projectId, Iterable<Long> longs) {
return jpaRepository.findAllById(longs);
}

@Override
public boolean existsAllById(String projectId, Collection<Long> longs) {
return jpaRepository.existsDistinctByIdIsIn(longs);
}

@Override
public <S extends ConfoundingVariableData> S save(String projectId, S entity) {
return jpaRepository.save(entity);
}

@Override
public Optional<ConfoundingVariableData> findById(String projectId, Long aLong) {
return jpaRepository.findById(aLong);
}

@Override
public long countVariablesOfExperiment(String projectId, String experimentId) {
return jpaRepository.countByExperimentIdEquals(experimentId);
}

@Override
public void deleteById(String projectId, Long aLong) {
jpaRepository.deleteById(aLong);
}

@Override
public void deleteAllById(String projectId, Iterable<Long> longs) {
jpaRepository.deleteAllById(longs);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*
* @since 1.0.0
*/
public interface QbicSampleDataRepo {
public interface SampleDataRepository {

/**
* Creates a reference to one or more {@link Sample}s in the data repository to connect project data.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import life.qbic.projectmanagement.domain.model.sample.SampleId;
import org.springframework.data.jpa.repository.JpaRepository;

public interface QbicSampleRepository extends JpaRepository<Sample, SampleId> {
public interface SampleJpaRepository extends JpaRepository<Sample, SampleId> {

Collection<Sample> findAllByExperimentId(ExperimentId experimentId);

Expand Down
Loading

0 comments on commit 7042182

Please sign in to comment.