Mapping a Cassandra Enum column to a non Name or Ordinal Value - enums

I have an Enum
#AllArgConstructor
public enum SomeEnum {
SOMETHING (1,"ABC","xxx","yyy"),
SOMETHING_ELSE (2,"DEF","zzz","aaa"),
SOMETHING_ELSE_2 (3,"GHI","yyy","bbb")
final int val1;
final String value
final String val2;
final String val3;
}
I have a cassandra entity
import org.springframework.data.cassandra.core.cql.PrimaryKeyType;
import org.springframework.data.cassandra.core.mapping.PrimaryKeyClass;
import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn;
import lombok.Data;
#Data
#PrimaryKeyClass
public class MyModel {
...........
..............
#PrimaryKeyColumn(name = "mycolumn", type = PrimaryKeyType.CLUSTERED, ordinal = 1)
private SomeEnum someenum;
--------------
}
Now I want to save SomeEnum.value in cassandra mycolumn column
For example ABC not SOMETHING
and DEF not SOMETHING_ELSE etc.
By default cassandra use enum member name for converting.
So my Question is
How can I create a customerConverter for an Enum type column in cassandra Entity?
Note-
In Java code, Entity class the column is of type enum as shown above, but in cassandra table mycolumn type is TEXT.

Related

jHipster use enum in specification to find only entites that have one concrete value of Enum

There is entity:
#Getter
#Setter
#ToString()
#Entity
#Table
#Builder
#NoArgsConstructor
#AllArgsConstructor
class DocumentEntity implements Serializable {
(...)
#Enumerated(EnumType.STRING)
public DocumentStatus documentStatus;
}
I have serializable class:
#Data
#NoArgsConstructor
public class DocumentCriteria implements Serializable, Criteria {
private StringFilter documentStatus;
(...)
}
and auto generated class:
#Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
#StaticMetamodel(DocumentEntity.class)
public abstract class DocumentEntity_ {
public static volatile SingularAttribute<DocumentEntity, DocumentStatus> documentStatus;
public static final String DOCUMENT_STATUS = "documentStatus";
(...)
}
DocumentStatus is simple enum:
public enum DocumentStatus {
A,
B
}
I want to add specification that I search only entites with DocumentStatus set to A:
private Specification<DocumentEntity> createSpecification(DocumentCriteria criteria) {
Specification<DocumentEntity> specification = Specification.where(null);
if (criteria != null) {
StringFilter globalStringFilter = new StringFilter();
globalStringFilter.setContains(DocumentStatus.A.name());
specification.and(buildStringSpecification(globalStringFilter, DocumentEntity_.documentStatus));
I have an error here saying:
Required type:
SingularAttribute
<? super DocumentEntity,
String>
Provided:
SingularAttribute
<DocumentEntity,
DocumentStatus>
How can I search for it?
I tried also:
specification = specification.and(buildSpecification(criteria.getDocumentStatus(), DocumentStatus.A.name());
but it says:
Cannot resolve method 'buildSpecification(StringFilter, String)
Should i use other type than StringFilter even though database type is varchar ?
Does trying using String like: DocumentStatus.A.name() does not help here ?
Another option that comes in my head is writing something like that:
RangeFilter<DocumentStatus> globalStringFilter = new RangeFilter<DocumentStatus>();
List<DocumentStatus> documentStatuses = new ArrayList<>();
documentStatuses.add(DocumentStatus.A);
globalStringFilter.setIn(documentStatuses);
specification.and(buildRangeSpecification(globalStringFilter, DocumentEntity_.documentStatus));
And changing DocumentCriteria documentStatus field type to RangeFilter.
Above option does not seem to take effect when running application.
Solution:
RangeFilter<DocumentStatus> globalStringFilter = new RangeFilter<DocumentStatus>();
List<DocumentStatus> documentStatuses = new ArrayList<>();
documentStatuses.add(DocumentStatus.A);
globalStringFilter.setIn(documentStatuses);
specification=specification.and(buildRangeSpecification(globalStringFilter, DocumentEntity_.documentStatus));
And changing DocumentCriteria documentStatus field type to RangeFilter.
Make sure that specification= is present, so that result is consumed.

How do i create new table in database from same entity JPA Spring boot?

I want to create a new table every day with the full date as table name if the day is new create table for the that day
I have seen that when I change #Table(name="") name to a new string it make a new table but I can't automate this work
#Entity
#Table(name="orders_25_10_2021")
public class game2data {
#Id
private int cid;
private String name;
private Integer address;
private Integer gender;
private String date;
private String Done;
In simple words, I want to pass the name of #Table(name="") as a variable with dynamic according to date.
You can achieve this custom naming strategy by extending SpringPhysicalNamingStrategy and overriding its toPhysicalTableName method :
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
import org.springframework.context.annotation.Configuration;
#Configuration
public class TableNamingStrategy extends SpringPhysicalNamingStrategy {
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd_MM_YYYY");
public static final PhysicalNamingStrategyStandardImpl INSTANCE =
new PhysicalNamingStrategyStandardImpl();
#Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
if (!name.getText().equals("game2data"))
return name;
StringBuilder customName =
new StringBuilder("orders").append('_').append(DATE_FORMATTER.format(LocalDate.now()));
return new Identifier(customName.toString(), name.isQuoted());
}
}
and registering it in your application.properties:
spring.jpa.hibernate.naming.physical-strategy=com.stackoverflow.questions.TableNamingStrategy
and removing the #Table annotation from the game2data entity.
This method is limited by the fact table names are determined at application start-up.
As a proof of concept, here's a way to update the table name every day by extending StatementInspector. By using this, you won't be able to read old data. You'll also have to use custom implementations of the JpaRepository's methods to create the new table every day before you insert data in it.

How do I annotate a JPA Entity to use a Date with OracleDB?

I have a OracleDB column of type Date. I can make a JPA entity that does not include this column and everything works great. However when I try to add this column like...
import java.sql.Timestamp
case class MyDate(
#Column(
name = "MY_DATE",
)
#BeanProperty date: Timestamp
) {
def this() {
this(null)
}
...
}
I get...
ORA-01747: invalid user.table.column, table.column, or column specification
How do I properly annotate a JPA Date Entity using Oracle?
I am not going to accept this because I would like to do it in the constructor like I described but this does work....
import java.sql.Timestamp
case class MyDate() {
#Column(
name = "MY_DATE",
)
#BeanProperty
val date: Timestamp = null
...
}

Jpa Specification search like in a composed field

I have an Entity class and also a JPARepository:
#Entity
class MyClass(){
Integer id;
String type;
String coin;
}
and in my service I create and return another model class which has a String param:
class ResponseClass(){
String txId;
}
txId = String.format(myModel, type.chartAt(0),coin.chartAt(0), new MyClass().getId())
I returned to controller new ResponseClass().setTxId(txId)
How can I make a query which search in my table after txId value? I have to use JPA Specification.
Example of table:
ID Type Coin
001 Deposit USD
and my is txID = DU-001. I want to search in the table after this composed value and return the entry!

Add Two Conditions in JpaRepository

i am trying to do a POC - using JpaRepository filter out the data by adding two conditions.
I have written a code like below
public interface TemplateRepository extends JpaRepository<Template, Long> {
List<Template> findByTemplateNameContains(String templateName);//This is Working Fine
List<Template> findByTemplateNameAndActiveFlagContains(String templateName, String activeFlag);// My POC
}
templateName column is a VARCHAR2 and activeFlag is a Char in the Oracle Database. I am trying to filter the data with both templatename
and activeFlag.
I pass the input object in SoapUI app (POST) request.
{
"netting":"karu_test",
"activeFlag": "Y"
}
but I get the below error
"Parameter value [%Y%] did not match expected type [java.lang.Character (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [%Y%] did not match expected type [java.lang.Character (n/a)]"
I understand this error like, the ACTIVE_FLAG column is CHAR(1) so type mismatch happend. But how to achieve the same functionality ?
More over .. how to use multiple table joins and condition in JpaRepository
I changed the type of activeFlag to Char still i get the same error.
Template class
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
#Entity
#Table(name="TEMPLATE_DEF")
#Getter
#Setter
public class Template {
#Column(name="TEMPLATE_ID")
#Id
private String nettingTemplateId;
#Column(name="TEMPLATE_NAME")
private String templateName;
#Column(name="LAST_UPDATE")
private Date lastUpdate;
#Column(name="UPDATE_USER_ID")
private Integer updUsrId;
#Column(name="ACTIVE_FLAG")
private char activeFlag;
#Column(name="VERSION")
private Integer Version;
#Column(name="CREATION_DATE")
private Date creationDate;
#Column(name="CREATE_USER_ID")
private Integer createUsrId;
}
Please try the below JPA Query
List<Template> findByTemplateNameContainingAndActiveFlagContaining(String templateName, Character activeFlag);
Your Active flag is a char so no point in putting containing for activeFlag rather do a exact match, change method signature to
List<Template> findByTemplateNameContainsAndActiveFlag(String templateName, char activeFlag);// My POC
I have tested it it will match name with like and activeFlag based on value of it

Resources