Is it possible read YAML property from annotation? - spring

I need pass a db shchema to annotation, it is possible read from annotation without create a intermediate variable?
Something like that -
#Id
#SequenceGenerator(name = "${DB_ESCHEMA} + SEQ.ID")
private Long id;

No you cannot use Spring EL in JPA annotations.
But why do you are you using the schema name? Isn't it the same as the rest of the tables?

Related

How to make #Indexed as unique property for Redis model using Spring JPA Repository?

I have a model class that I store in Redis and I use Jpa Repository with Spring java. Normally(not with redis) jpa repository is saving the new data or updates(conditionally) if the given model is already exist in Db. Here, I want to add new item to redis but if it is not already exists on db otherwise update it just like usual Jpa implementation.
Here is my model:
#Getter
#Setter
#RedisHash("MyRecord")
public class MyRecordRedisModel {
private String id;
#Id
#Indexed
private String recordName;
private Date startDate;
private Date endDate;
}
And my repository class is just a normal spring jpa repo as follows:
#Repository
public interface IFRecordRedisRepository extends JpaRepository<IFRecordRedisModel, String> {
Page<IFRecordRedisModel> findAll(Pageable pageable);
}
Unique key must be the name (I totally do not care about uniquiness of the id). Thus, if the name is already exist in Db than do not add it again. I marked it as Indexed but still it is adding same data (with same recordName).
How can I make it unique?
This would require an additional query, but I think this solution would work for you. You can use query by Example to check if there exists a record with that name, and save conditionally, or do something else if it already exists.
IFRecordRedisModel exampleRecord = new IFRecordRedisModel();
exampleRecord.setRecordName(inputRecord.getRecordName());
if (!repository.exists(Example.of(exampleModel)))
repository.save(inputRecord);
else ..... // do something else

Spring data #ReadOnlyProperty causing unexpected behavior

I have a Model attribute that needs to set #ReadOnlyProperty so that it won't persist after first inserting the line.
Assume my model like below
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(updatable = false, nullable = false)
#JsonIgnore
private Long id;
#Column(unique = true, nullable = false)
#ReadOnlyProperty
private String openId;
}
then I have a UserRepository:
public interface UserRepository extends JpaRepository<User, Long> {
}
then I provide 2 Restful API for POST and PUT.
The create user operation code is as simple as below:
user.setOpenId(1);
userRepository.save(user)
The update user operation is almost the same:
user.setOpenId(2);
user = userRepository.save(user);
I'm surprised that the user's openId attribute will be changed, after POST and then PUT, the returned user object will have the changed value.(user.getOpenId() == 2)
It looks like #ReadOnlyProperty not working, I'm using the RELEASE version of spring-boot-starter-data-jpa. Can someone help explain?
It seems that #ReadOnlyProperty doesn't work. The following bug report is open for years:
Properties with #ReadOnlyProperty annotation are being nullified in PATCH requests
If you want to deny modifying the property via Spring Data Rest endpoints, use the #JsonProperty(access = Access.READ_ONLY) annotation. It affects the JSON deserialization, so the annotated property never reaches Spring Data Rest.
If you also need to deny the writing of the property via Spring Data JPA, you can use the following JPA annotation: #Column(updatable=false) It denies the override on the underlaying JPA level, instead of Spring Data JPA level.

EclipseLink 2.1.3, Oracle 11g, return PK after persist with container managed persistence

I'm using EclipseLink 2.1.3 with a container managed EntityManager to interface with an Oracle 11g DB.
I want to have an Entity's #Id variable updated immediately after I call persist() on the EM.
What is the correct strategy to do so with an Oracle DB?
None of the examples I've found on this site deal with this problem with container managed persistence.
The Entity looks like this:
#Entity
#Table(name = "ANNOUNCEMENT_DELIVERY_LOG")
public class AnnouncementDeliveryLog implements Serializable {
#Id
private BigDecimal id;
#ManyToOne
#JoinColumn(name = "ANNOUNCEMENT_ID ")
private Announcements announcement;
public AnnouncementDeliveryLog() {
}
}
Do I need to add something like the following?
#Column(nullable = false)
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ANNOUNCEMENT_DELIVERY_LOG_SEQ")
#SequenceGenerator(name="ANNOUNCEMENT_DELIVERY_LOG_SEQ", sequenceName="ANNOUNCEMENT_DELIVERY_LOG_SEQ")
To persist the Entity I'm just calling persist(). Do I also need to call flush()?
Yes, you have to provide a #SequenceGenerator annotation in order that JPA automatically assigns a new ID to the entity during persist().
A flush is not necessary.

Spring data jpa : how to retrieve data using #ElementCollection?

Here is a part of Files.java
#Entity(name="files")
public class Files {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
#ElementCollection
private List<String> filenames= new ArrayList<String>();
//<< getter and setter >>
}
it is correctly created the table 'Files' and 'Files_filenames' on mySql
and I can put data there on Controller with it
Files files = new Files();
files.setTitle(ufile.getTitle());
files.setFilenames(Arrays.asList(ufile.getFilename().split(",")));
so far, everything looks ok
However, when I try to get the data from the database, the filename always returns something like 'persistentbag' not ArrayList.
I would like to know how to get ArrayList from the database
I'm using Spring data JPA using Hibernate as a Jpa vendor.
Thanks in advance
PersistentBag is a List (i.e., it implements List), therefore you can use it as a regular List. There is no need to care about actual implementation of that List in this case.

When are Entities-Classes enhanced and what for? jpa, spring, hibernate, javassist

I am using spring 3.0.6, jpa 2.0, hibernate 3.6.8.
My question is, in which situations is javassist used to create "proxy" for a EntityClass? And what is reason of this proxy?
I have the following Entity:
#Entity
public MyEntity{
..
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "adresseID")
private Adresse adresse;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "myEntity")
private List<Parameter> parameters;
..
}
When I load a MyEntity from db, the class of entity is something like MyEntity__$$_javassist. Why is it done? What for? I think that just regular class MyEntity can be used here .
To implement lazy loading, we can:
for #OneToMany - PersistenceBag can be used here
for #ManyToOne - here should be used "enchancedClass" like Adress_$$_javassist
So what is reason for enchancing MyEntity? Where I can read something more about it? Which book/article/blog can you recommend me?
The primary reason why entity classes are enhanced is that JPA (or Hibernate) need to track entity objects state.
In particular JPA must be aware if given entity field is "dirty" - it was modified by user, but this change is not yet reflected in database, so JPA must synchronize it with database when transaction is commited.
The other case is "loaded" state of the entity field. Any field can be assigned to be lazy loaded. When such field is about to be used, JPA must be aware that database query has to be performed to initialize value of that field.
Hibernate's default is to use runtime enhacement - the proxy is just a subclass of the entity with extra stuff added.
Some general ideas are outlined here.

Resources