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

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
...
}

Related

Spring Boot #PrePersist does not work properly

I have a Spring Boot application with Kotlin and want to store the creation timestamp and the last updated timestamp. The following code should do the trick:
#Entity
data class Entity(
// ...
) {
lateinit var createdAt: Instant
lateinit var updatedAt: Instant
#PrePersist
private fun onCreate() {
createdAt = Instant.now().also { updatedAt = it }
}
#PreUpdate
private fun onUpdate() {
updatedAt = Instant.now()
}
}
The PostgreSQL table looks like this:
create table entity
(
-- Other fields...
created_at timestamp not null,
updated_at timestamp not null
);
When i now try to call repository.save(entity) I get the following error:
Caused by: org.postgresql.util.PSQLException: ERROR: null value in column "created_at" violates not-null constraint
updatedAt however has the correct value which means #PreUpdate is working as expected. Does anyone know what is the problem here?

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

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.

Inserting a ZonedDateTime value to Oracle Timestamp With Timezone Column With JPA

In my SpringBoot project, I am trying to insert a ZonedDateTime value to an Oracle database where the column type is specified as TIMESTAMP WITH TIMEZONE. When I do that, the inserted value gets converted to the JVM timezone and gets inserted. However, what I expect is to insert the value in ZonedDateTime property as it is.
For example, if the ZonedDateTime value is set to 2020-05-16T12:12:24+02:30[US/Denver], then I expect to write to DB the same value and read from DB the same value. Is there any way I can do this with Hibernate and JPA
#Entity
class MyEntity{
ZonedDateTime myDateTimeWithTimeZone;
}
#Repository
public interface MyRepository extends JpaRepository<MyEntity, Long>
{
}
This is how i am going to use it,
MyEntity myEntity = new MyEntity();
myEntity.setMyDateTimeWithTimeZone(ZoneDateTime.now('US/Denver')) // This timezone can be anything depending on userInput
myRepository.save(myEntity);

Why doesn't Mybatis map a simple ENUM correctly?

I'm not doing anything out of the ordinary from what I can tell. I have a spring boot application using mybatis:
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.1'
I have an application.properties config for mybatis that is pretty simple:
## MyBatis ##
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.default-statement-timeout=30
My database table looks like this:
CREATE TABLE workspace_external_references (
id CHAR(36) PRIMARY KEY,
workspace_id CHAR(36) NOT NULL,
site VARCHAR(255) NOT NULL,
external_id VARCHAR(255) NOT NULL,
created_at DATETIME(6) NOT NULL DEFAULT NOW(6),
updated_at DATETIME(6) NOT NULL DEFAULT NOW(6),
FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE
)
With just a single entry like this:
'a907c0af-216a-41e0-b16d-42107a7af05f', 'e99e4ab4-839e-405a-982b-08e00fbfb2d4', 'ABC', '6', '2020-06-09 00:19:20.135822', '2020-06-09 00:19:20.135822'
In my mapper file I'm doing a select of all references like this:
#Select("SELECT * FROM workspace_external_references WHERE workspace_id = #{workspaceId}")
List<WorkspaceExternalReference> findByWorkspace(#Param("workspaceId") final UUID workspaceId);
And the java object that this is supposed to map to looks like this:
public class WorkspaceExternalReference {
private UUID id;
private UUID workspaceId;
private Sites site;
private String externalId;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
public WorkspaceExternalReference(
final Sites site,
final UUID workspaceId,
final String externalId) {
this.site = site;
this.workspaceId = workspaceId;
this.externalId = externalId;
}
}
public enum Sites {
ABC, XYZ;
}
Sooooo why doesn't this work? I get this error back:
Caused by: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'id' from result set. Cause: java.lang.IllegalArgumentException: No enum constant com.acme.Sites.a907c0af-216a-41e0-b16d-42107a7af05f
When there is no default constructor, you need to let MyBatis know which columns to pass to the constructor explicitly (in most cases).
With annotations, it would look as follows.
You can use <resultMap> and <constructor> in XML mapper.
#ConstructorArgs({
#Arg(column = "site", javaType = Sites.class),
#Arg(column = "workspace_id", javaType = UUID.class),
#Arg(column = "external_id", javaType = String.class)
})
#Select("SELECT * FROM workspace_external_references WHERE workspace_id = #{workspaceId}")
List<WorkspaceExternalReference> findByWorkspace(#Param("workspaceId") final UUID workspaceId);
Other columns (i.e. id, created_at, updated_at) will be auto-mapped via setters (if there are) or reflection.
Alternatively, you can just add the default (no-arg) constructor to the WorkspaceExternalReference class. Then all columns will be auto-mapped after the class is instantiated.
Note: To make it work, there needs to be a type handler registered for UUID, but you seem to have done it already (otherwise the parameter mapping wouldn't work).

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