How to search if bytearray contains element from other array - java

I have an entity called Recipe and I created a Repository which extends JpaRepository and I would like to search up the recipes which contains every element of the search array for dietLabelList.
#Getter
#Setter
#Entity
#NoArgsConstructor
#RequiredArgsConstructor
#ToString
#Table(name = "recipe")
public class Recipe {
#Column(name = "id", nullable = false)
#Id
#GeneratedValue
private UUID rid;
#Column(name = "title", nullable = false)
private String title;
#Column(name = "dietLabelList", nullable = false)
private UUID[] dietLabelList;
}
#Repository
public interface RecipeRepository extends JpaRepository<Recipe, UUID> {
List<Recipe> findByTitleContaining(String title);
List<Recipe> findByDietLabelList(UUID[] dietLabels);
}
e.g. I have a recipe that has as a dietLabelList like this one ["Balanced", "High-Fiber", "High-Protein"] and findByDietLabelList(["Balanced", "High-Fiber"]) should be able to find it. Is something like possible with JpaRepository?

You can use QueryParam and specify your custom Query
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
#Repository
public interface RecipeRepository extends JpaRepository<Recipe, UUID> {
List<Recipe> findByTitleContaining(String title);
#Query(value = "SELECT r FROM Recipe r WHERE r.dietLabels in :dietLabels")
List<Recipe> findByDietLabelList(#Param("dietLabels") UUID[] dietLabels);
}

Related

repositoryItem reader org.springframework.data.mapping.PropertyReferenceException: No property 'MANIFBURENREGMANIF' found for type 'ArticleManifeste'

org.springframework.data.mapping.PropertyReferenceException: No property 'MANIFBURENREGMANIF' found for type 'ArticleManifeste'
**This is my code **
#Entity
#Table(name="ARTICLEMANIFESTE")
#Data
#Builder(toBuilder = true)
#AllArgsConstructor
#NoArgsConstructor
#FieldDefaults(level= AccessLevel.PRIVATE)
#IdClass(ArticleManifesteKey.class)
public class ArticleManifeste implements Serializable {
static final long serialVersionUID = -7273917648454868311L;
#Id
#Size(max = 3)
#NotNull
#Column(name="MANIFBURENREGMANIF", length=3, nullable = false)
String manifBureauEngManif;
#Id
#Size(max = 4)
#NotNull
#Column(name="MANIFANNEEENREGMANIF", length=4, nullable = false)
String manifAnneeEngManif;
...........
}
Entity key
#Data
#AllArgsConstructor
#NoArgsConstructor
#Builder(toBuilder = true)
#FieldDefaults(level= AccessLevel.PRIVATE)
public class ArticleManifesteKey implements Serializable {
static final long serialVersionUID = 203621482537663708L;
#Id
#Column(name="MANIFBURENREGMANIF", length=3, nullable=false)
String manifBureauEngManif;
/**
* Implementation field for persistent attribute: manifanneeengmanif
*/
#Id
#Column(name="MANIFANNEEENREGMANIF", length=4, nullable=false)
String manifAnneeEngManif;
........
}
Some error when use CrudRepository
#Repository
public interface ArticleManifesteRepository extends PagingAndSortingRepository<ArticleManifeste, String> {
#Override
Page<ArticleManifeste> findAll(Pageable pageable);
}
Also when i use the crudRepo and here change return type to list
#Service
public interface ArticleManifesteService {
public Iterable<ArticleManifeste> findAll();
}
Implementation of service
#Service
public class ArticleManifesteServiceImp implements ArticleManifesteService {
#Autowired
ArticleManifesteRepository articleManifesteRepository;
#Override
public Iterable<ArticleManifeste> findAll() {
return articleManifesteRepository.findAll();
}
}
I'm using this reader in a batch configuration, I'm trying to read data from the Article Manifest table.
#Bean
public RepositoryItemReader<ArticleManifeste> reader() {
RepositoryItemReader<ArticleManifeste> reader = new RepositoryItemReader<>();
reader.setRepository(articleManifesteRepository);
reader.setMethodName("findAll");
List<Object> queryMethodArguments = new ArrayList<>();
reader.setPageSize(100);
Map<String, Direction> sorts = new HashMap<>();
sorts.put("MANIFBURENREGMANIF", Direction.ASC);
reader.setSort(sorts);
return reader;
}

How to get parent entity with all child entities and child entities of children in Spring/JPA/Hibernate with Lombok

I have these entities where Shop entity is parent:
#Data
#NoArgsConstructor
#Entity
#DynamicUpdate
#Table(name = "Shop", schema = "public")
public class ShopDao {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
private String name;
private String processedStatus;
#OneToMany(mappedBy = "shopDao", cascade = CascadeType.ALL, orphanRemoval = true)
private List<BookDao> bookDaoList;
}
#Data
#NoArgsConstructor
#Entity
#ToString(exclude = {"shopDao"})
#Table(name = "Book", schema = "public")
public class BookDao {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
private String name;
private String author;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "other_id", referencedColumnName = "id")
private OtherDao otherDao;
#ManyToOne
#JoinColumn(name = "shop_id", nullable = false)
private ShopDao shopDao;
}
#Data
#NoArgsConstructor
#Entity
#ToString(exclude = {"bookDao"})
#Table(name = "Other", schema = "public")
public class OtherDao {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
private String metadata;
#OneToOne(mappedBy = "otherDao", fetch = FetchType.EAGER)
private BookDao bookDao;
}
And these are repos:
#Repository
public interface ShopRepo extends JpaRepository<ShopDao, Long> {
#EntityGraph(attributePaths = {"bookDaoList"})
List<ShopDao> findAllByProcessedStatus(String processedStatus);
}
#Repository
public interface BookRepo extends JpaRepository<BookDao, Long> {
}
#Repository
public interface OtherRepo extends JpaRepository<OtherDao, Long> {
}
When i'm using findAllByProcessedStatus() function, i get BookList inside Shop object correctly, but each Book can't reach their Other objects and i get LazyInitializationException:
screenshot
How do i fix that problem?
Actually, with spring data's #EntityGraph all you need is :
#Repository
public interface ShopRepo extends JpaRepository<ShopDao, Long> {
#EntityGraph(attributePaths = {"bookDaoList.otherDao"})
List<ShopDao> findAllByProcessedStatus(String processedStatus);
}
This is the most convenient way.
For more complex relations, you could define a #NamedEntityGraph, and provide subgraphs, like so.
What I find intriguing, is that the BookDao is the owner of this relation, so I would expect it to be eagerly loaded, since you haven't specified a the Lazy fetch mode explicitly ...

Spring Data JPA: FindBy on Join Column

I have setup two entities like below in a one-to-one mapping and I am trying to query on the joincolumn like below in my repository:
#Entity
#Table(name = "a")
#AllArgsConstructor
#NoArgsConstructor
#Data
#EqualsAndHashCode(callSuper=false)
public class A extends Auditable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(unique = true)
#Size(min = 1, max = 100)
private String name;
}
#Entity
#Table(name = "b")
#AllArgsConstructor
#NoArgsConstructor
#Data
#EqualsAndHashCode(callSuper=false)
public class B extends Auditable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
#Size(min = 1, max = 100)
private String name;
#OneToOne
#JoinColumn(name="aId", referencedColumnName = "aId")
private A aId;
}
In my BRepository.java, I am trying to do this:
#Component
public interface BRepository extends JpaRepository<B, Long> {
List<B> findAllBByA_aId(String aId);
}
I get the following error:
No property a found for type B! Did you mean 'aId'?
Is this not the right way to query on a join column in spring-data??
Since you have not defined the column name for id in A then the column name will defaults to id. Then in class B, you should change the referencedColumnName to id (or else you can simply skip the referencedColumnName attribute since it can be derived directly from the target entity in an OneToOne relationship)
#Entity
#Table(name = "b")
#AllArgsConstructor
#NoArgsConstructor
#Data
#EqualsAndHashCode(callSuper=false)
public class B extends Auditable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
#Size(min = 1, max = 100)
private String name;
#OneToOne
#JoinColumn(name="aId", referencedColumnName = "id")
private A aId;
}
In repository, you need to annotate it with #Repository annotation to let Spring know it should be treated as a Repository Bean.
#Repository
public interface BRepository extends JpaRepository<B, Long> {
#Query(value="select b from B b where B.aId.id=?1")
List<B> findAllBByA_aId(String aId);
}
or you can use SPeL directly,
#Repository
public interface BRepository extends JpaRepository<B, Long> {
List<B> findAllByaIdId(String aId);
}

Error ConverterNotFoundException Springboot Java

I am working on a project using Springboot to create API to call all provinces in the list. So first i create an entity class
package example.parameter.entity;
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import java.util.List;
#Data
#Entity
#Table(name = "provinces",indexes = {
#Index(name = "PROVINCES_INDX_0", columnList = "name")
})
public class Province extends BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "provinces_generator")
#SequenceGenerator(name = "provinces_generator", sequenceName = "provinces_seq", allocationSize = 1)
#Column(name = "id", updatable = false, nullable = false)
private Long id;
#Column(name = "is_deleted")
private Boolean isDeleted;
#OneToMany(mappedBy = "province", cascade=CascadeType.ALL, orphanRemoval = true)
private List<Regency> regencies;
#NotBlank
#Column(name = "name")
private String name;
}
and then I created this responseDTO
package example.parameter.api.response;
import lombok.Data;
#Data
public class ProvinceResponseDTO {
private String id;
private String name;
}
after that I create the repository
package example.parameter.repository;
import example.parameter.api.response.ProvinceResponseDTO;
import example.parameter.entity.Province;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
public interface ProvinceRepository extends JpaRepository<Province,Long> {
public List<ProvinceResponseDTO> findAllByIsDeleted(Boolean isDeleted);
}
when I am trying to hit the API I am getting this error on data layer.
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [example.parameter.entity.Province] to type [example.api.response.ProvinceResponseDTO]
I don't know thy this is happening, any solution to fix this issue?
Part:1
JpaRepository Query creation from method name should have the default return type of the entity object. In your case, your repository is for the Province entity. So, it should be like
public interface ProvinceRepository extends JpaRepository<Province, Long> {
public List<Province> findAllByIsDeleted(Boolean isDeleted);
}
Reference:-
https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaRepository.html
Part: 2
If you need to return a custom object from the query creation from a method name, then you can use dynamic projections like below:-
public interface ProvinceRepository extends JpaRepository<Province, Long> {
public <T> List<T> findAllByIsDeleted(Boolean isDeleted, Class<T> dynamicClassType);
}
while calling this method you define like
provinceRepository.findAllByIsDeleted(true, ProvinceResponseDTO.class)
Reference:- https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections.dtos

Search failed by child type

I have an abstract class and its child.
#Getter
#Setter
#Builder
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table
#Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
#EntityListeners(AuditingEntityListener.class)
#DiscriminatorValue(EntityEnum.Values.APPEALS)
public class Appeals extends EntityAbstract {
public Appeals(String content) {
this.content = content;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Type(type = "text")
#Column(name = "guid", updatable = true, insertable = true)
private String guid;
#Type(type = "jsonb")
#Column(name = "content", columnDefinition = "jsonb")
private String content;
#LastModifiedDate
#Column(name = "changed_at", columnDefinition = "TIMESTAMP")
private LocalDateTime changedAt;
#CreatedDate
#Column(name = "created_at", columnDefinition = "TIMESTAMP")
private LocalDateTime createdAt;
}
#ToString
#Getter
#Setter
#Entity
#Table(name = "entity_parent")
#Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
#EntityListeners(AuditingEntityListener.class)
#Inheritance(strategy = InheritanceType.JOINED)
#DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
//#MappedSuperclass
#TypeDefs({#TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)})
public abstract class EntityAbstract implements Content {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "guid")
private String guid;
#Version
private Integer version;
}
I use Spring Data and try to make a request:
public interface EntityRepository extends JpaRepository<EntityAbstract, Long>, JpaSpecificationExecutor<EntityAbstract> {
#Query("SELECT e FROM EntityAbstract e WHERE TYPE(e) = :type AND e.guid = :guid")
<E extends EntityAbstract> E findByGuidAndType(String guid, Class<E> type);
}
I make the call like this:
entityRepository.findByGuidAndType(guid, Appeals.class);
I get this error:
org.hibernate.QueryException: Named parameter [type] not set; nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: Named parameter [type] not set
What am I doing wrong?
I believe that there is a much more easy way to solve the problem. You are using a type class parameter Class<E> in the findByGuidAndType(String guid, Class<E> type) method whereas you shoudl use a <? extends EntityAbstract> type because in a first case Spring knows nothing about a E but if you will declare it as an inheritor of the EntityAbstract Spring will start match classes properly. So the repo interface will be like this:
public interface EntityRepository extends JpaRepository<EntityAbstract, Long>, JpaSpecificationExecutor<EntityAbstract> {
#Query("SELECT e FROM EntityAbstract e WHERE TYPE(e) = :type AND e.guid = :guid")
<E extends EntityAbstract> E findByGuidAndType(String guid, Class<? extends EntityAbstract> type);
}
At least it works for me as expected
This is how I solved the problem:
#Override
#Transactional
public ResponseDto findByGuid(String guid, Class<?> name) {
Optional<EntityAbstract> guid1 = entityRepository.findOne(((Specification<EntityAbstract>)
(root, query, builder) ->
findInField(guid, () -> root.get("guid"), builder, query))
.and((root, query, builder) ->
builder.equal(root.type(), builder.literal(name))
)
);
EntityAbstract entityAbstract = guid1.orElse(null);
return representateToDto(entityAbstract);
}
private Predicate findInField(Object element,
Supplier<Path<?>> pathSupplier,
CriteriaBuilder builder,
CriteriaQuery<?> query) {
query.distinct(true);
return StringUtils.isEmpty(element)
? builder.conjunction()
: pathSupplier.get().in(element);
}

Categories