Spring jpa: add field to #Entity class. Should this result in the automatic addition of a new column in the underlying table? - database

I have a class that is an entity using spring jpa.
I want to add a new field to this class. A private boolean with getter/setter methods.
I have heard that I should be able to just add the field to the class and spring jpa should add the column to the underlying table on next run.
The behaviour that I am actually seeing is that it throws an error.
Is anyone familiar with this operation? Is it true that spring jpa should handle the column addition automatically?

Related

Is there a transient kind of annotation for Spring-data-mongodb

I just changed my springboot from using Postgresql to mongo, i am trying to get the mongodb to leave out a property when storing an object in MongoDB, but the #Transient field doesnt work. Is there a way to do this ?
#Transient is supposed to work with Spring Data MongoDB.
From the Spring Data MongoDB documentation:
#Transient: By default all private fields are mapped to the document,
this annotation excludes the field where it is applied from being
stored in the database
If it isn't working for you, I suggest including your code in your question.
Note that if you forgot to add #Transient and added some data to your database, then later added #Transient to a field, Spring Data Mongo isn't going to go through the database collection and delete that field from all the documents that currently have it, it just won't include that field in any new documents it saves to the collection.

Variable datasource based on user

I'm currently developing a back end and having my first run in with security laws etc. and it has complicated the design of my DB slightly:
Specification
Central server for app with DB containing limited user information (user_id, email, password (hashed and salted)) can be anywhere.
Organisations making use of our service require that all other information be stored in-house, so the database for that particular organisation is in their building.
The user IDs in our central database are used by multiple types of users in these organisations databases, where more info about that user is stored (phone number, name, address...)
Problem
With Spring Boot, I need to make it so the datasource used is determined by which user makes the request. I map users to their corresponding organisation's database within the central server so the information is there, but I'm not sure how to make this variable.
I understand there are methods involving adding another database config in the application.properties file. But as far as I'm aware this can't be changed (easily) once the server is deployed and running without a full redeploy, and I'm hoping to build this in such a way that adding another organisation only involves setting up their db, and adding another database details to the central server.
Extra detail
I'd like to use CrudRepository with hibernate entities for this. I plan on only generating user IDs on the central server.
Any pointers would be awesome.
Thanks!
The terminology for this is database multi-tenancy. There are multiple strategies for multi-tenancy: different databases, different schemas in the same database, and the same schema on one database with a defined discriminator.
You basically create a DataSourceBasedMultiTenantConnectionProviderImpl class which provides the connection to a datasource based on which tenant is requesting it, and a CurrentTenantIdentifierResolverImpl class which identifies who is the requesting tenant.
You can read more about it here. Since your tenants each have their own database, you would probably want to focus on the multi-tenancy separate database approach. It worked fine with CrudRepository when I implemented it. You also might want to find your own way of creating the tenant map, since I had 2 tenants and no need to add more at any point.
Heres a sample of the connection provider from when I implemented this:
public class DataSourceBasedMultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
private static final String DEFAULT_TENANT_ID = "A";
#Autowired
private DataSource datasourceA;
#Autowired
private DataSource datasourceB;
private Map<String, DataSource> map;
#PostConstruct
public void load() {
map = new HashMap<>();
map.put("A", datasourceA);
map.put("B", datasourceB);
}
#Override
protected DataSource selectAnyDataSource() {
return map.get(DEFAULT_TENANT_ID);
}
#Override
protected DataSource selectDataSource(String tenantIdentifier) {
return map.get(tenantIdentifier);
}
}

WCF RIA SERVICES and EF 4.1

Do I have to explicitly add the [Include] attribute for any entities that has ICollection property so that result LoadOperation callback will populate my entity with its collection?
Querying the data from the Service is fine, but when being passed to the LoadOperation it doesn't add the collection of a certain entity. Does it have something to do with serialization/deserialization from the service message?
If yes, what is the reason why? I have used EF with DbContext.Includes in WPF but I did not have any issues with my T4 template generated items when I wanted to query my entity's collection.
The [Include] attribute is required to advise the WCF marshaller to serialize related entities. Specifically, MSDN advises
this attribute specifies that the association should be part of any
code-generated client entities, and that any related entities should
be included when serializing results to the client.
You will still need to use the query.Include() on your DbContext to retrieve the related data from the database.

google app engine: How do I add fields to an existent entity

I have a google app engine app where I would like to extend one of my Entity definitions. How would I ensure existent entity objects get the new fields properly initialized? Would the existent objects, the next time I query them, simply have default values? I'd like to add a StringListProperty.
If you add a new property to your model, existing entities will have the default value for it when you load them, if you supplied a default. They won't show up in queries for that value until you fetch them and store them again, though.
You will have to add the property to all of your existing entities, one by one.
You don't mention which language or API you are using. The exact details of the procedure will vary with your situation.
In general, the safest way to do this is to load up each entity with a API that doesn't validate your entities. In python, you can use Expando models. In java, you can use the low level datastore API. (trying this with JDO or JPA may not work) You now need to iterate through all existing entities. (try the new Mapper API to do this with relatively little fuss). For each entity, you will load it, add your new property, then put/save it back to the datastore. Now you can safely go back to a framework that validates your entities, like JDO or non-expando models.
This method applies to modifying the type of a property or deleting a property as well.

Storing username that last modified database row via EJB3.0 and JPA

I'd like to store username that has last modified table row to as a field in every table.
I have following setup: an user logs in, web layer calls some EJB 3.0 beans. Those EJB beans create and modify some JPA entities.
Now, I'd like that username (from weblayer) would be automatically stored to every JPA entity (and database row) that is created or modified during EJB method call.
I have this kind of table, (that is: every table has field modifier):
CREATE TABLE my_table (
some_data INTEGER,
modifier VARCHAR(20)
);
By automatically I mean, that I wouldn't need to set manually username to each entity inside EJB methods.
You could achive this by storing username to ThreadLocal variable and fetching username from ThreadLocal in JPA entity's EntityListener.
However this works only you are using a local EJB call, it will not work with EJB calls that cross JVM boundaries. I'd like to make this work over remote EJB method calls.
It this possible at all?
I am using Weblogic Server 10.3, EJB3.0 and EclipseLink JPA. I am also interested in hearing if this works with other JPA implementations.
You can use an EJB interceptor (#Around) on the EJB class to get the current user (using standard EJB api) and storing the name in the threadlocal variable. This would work transparently for remote and local calls.

Resources