Can value objects exist without Entities? - entity

I have a value object LoginAuth which contains the User authentication data for my secondary login system.
For every User it is optional to opt for the secondary login. So the User entity does not hold the LoginAuth value object but instead, the LoginAuth value object contains the User entity which it belongs to.
Since my database is normalized, I store this value object in a separate table where the user_id is the primary key (to ensure uniqueness).
As you can see, my value object doesn't live inside an entity but rather on it's own, but it does contain the entity it belongs to. My question is:
Can value objects exist without living inside entities?
Perhaps this would need to be an entity?
Each LoginAuth is supposed to be unique (only a unique User is allowed per LoginAuth), so there won't be any equals of this VO.
Note: My domain does not contain the application logic of this login system. Just the data it's supposed to handle. The application logic of it resides in the application layer of my model layer.

Can value objects exist without living inside entities?
Yes, they can. Some ephemeral Value Objects can be used in computations only and never persisted or related to an Entity.
However, this is not the type of object we're talking about here. LoginAuth obviously has a relationship to User and is persisted along with it.
To determine the direction of that relationship (what you're referring to as "living inside vs living outside"), you have to think in terms of obtaining references. In DDD, only Aggregate Roots can be rehydrated from storage (via Repositories). Once you have a reference to a Root, you can navigate to the Entities and Value Objects in its Aggregate.
If you follow DDD on that point, you aren't allowed to fetch a Value Object directly from the database. You have to load a whole aggregate, then obtain a reference to the VO through an Entity. Thus, you need to store a reference to the Value Object in an Entity, or at least have something built into the Entity that can produce the VO. In your example, this results in User holding the LoginAuth. The reverse alone wouldn't work.
Note: My domain does not contain the application logic of this login
system. Just the data it's supposed to handle. The application logic
of it resides in the application layer of my model layer.
If you take a CQRS approach to this and if the "login system" only implies reading the LoginAuth, you could bypass Repositories and use a Read Model to get the data you want directly.
However, this only covers the read side of things. I guess you would still want to be able to change a User's LoginAuth at some point and therefore still need a write-side Aggregate mutation for it.

The first things you have to remember is that Value Object must be equal when data inside is equal (not the reference).
Problem 1: If you have two LoginAuth reference which hold different object of User (which has the same data) that would make two LoginAuth unequal.
Problem 2: if someone alter state of first user reference? but second user reference still be the same, big problem gonna be happen. Do you understand?
Because User is an entity that has to have id, so LoginAuth can only hold id value inside, not whole User object, then you able to put LoginAuth into your database or serialize, send across your network, whatever you want.
Can value objects exist without living inside Entities? It's ok to do that, but you haven't try to break the concept of value object.
------- UPDATE --------
Perhaps this would need to be an entity? It's not necessary. You said that you normalized database and store LoginAuth in separate table, let's say login_auth table, which store id of User in column user_id, to make sure a single User have only one LoginAuth, make user_id as primary key (or unique) and make some double check in class which you use to put LoginAuth into database

Can value objects exist without Entities?
Yes, they can since Value Objects should not refer to an Entity.
Value Object has no identity and two value objects are equal when their attributes are identical. Usually Value Objects are used to describe Money, Address, Weight types. But LoginAuth can also be a Value Object with login and password attributes. It can also have and different other properties. Maybe expirationDate, lastLoginDate or something else...
Entity holds Value Objects usually. But even entity can't live without Aggregate Root if you want to persist it. The aggregate root should refer to the entity or to a list of entities.
Entities, Value Objects, Aggregates and Roots have their own specific role and usage in the Domain Model.
I have a value object LoginAuth which contains the User authentication
data for my secondary login system.
For every User it is optional to opt for the secondary login. So the
User entity does not hold the LoginAuth value object but instead, the
LoginAuth value object contains the User entity which it belongs to.
Domain model and database structure might be different.
When you design Domain Model you try to represent relations that exist in the target domain.
When you design database structure you think more about how data is stored, normalization and denormalization.
Domain entity User can be designed the following way and SecondaryLogin can be optional:
public class LoginAuth
{
public string Login { get; private set; }
public string Password { get; private set; }
public LoginAuth(string login, string password)
{
Login = login;
Password = password;
}
}
public class User
{
public LoginAuth PrimaryLogin { get; private set; }
public LoginAuth SecondaryLogin { get; private set; }
public User(string login, string password)
{
PrimaryLogin = new LoginAuth(login, password)
}
public User(
string login,
string password,
string secondaryLogin,
string secondaryPassword) : this(login, password)
{
SecondaryLogin = new LoginAuth(secondaryLogin, secondaryPassword);
}
}
If we start using ORM like Entity Framework or NHibernate they will generate the following table by default. They store Value Objects linked to an Entity together with it:
Users
=====================================================
Id (PK) | int | not null |
PrimaryLogin_Login | nvarchar(255) | null |
PrimaryLogin_Password | nvarchar(255) | null |
SecondaryLogin_Login | nvarchar(255) | null |
SecondaryLogin_Password | nvarchar(255) | null |
In one one of my projects I wanted to keep my database normalized and to store optional container for properties in separate table too.
Since my database is normalized, I store this value object in a
separate table where the user_id is the primary key (to ensure
uniqueness).
As you can see, my value object doesn't live inside an entity but
rather on it's own, but it does contain the entity it belongs to.
Because of NHibernate (Id column is required and tables are generated for entities only) it was needed to make it an Entity. But if no ORM is used and entities are loaded by yourself, you can store them as you wish.
ParentEntities
=====================================================
Id (PK) | int | not null |
Name | nvarchar(255) | not null |
OptionalEntities
=====================================================
Id (PK) | int | not null |
ParentEntityId (FK) | int | not null |
Login | nvarchar(255) | not null |
Password | nvarchar(255) | not null |
or it is also possible to make One-to-One relation that is not recommended and I'm not sure if it works for optional properties.
ParentEntities
=====================================================
Id (PK) | int | not null |
Name | nvarchar(255) | not null |
OptionalEntities
=====================================================
Id (PK) | int | not null |
Login | nvarchar(255) | not null |
Password | nvarchar(255) | not null |
In this case ParentEntities.Id is equal to OptionalEntities.Id when data is related to the same entity.

Related

Mapping between User and UserInfo

So lets say I have one entity
User:
id | username | password | role
Then I have two others which will represent additional information, NormalUserInfo and AdminUserInfo
NormalUserInfo:
id | bio | age
AdminUserInfo:
id | level | status
So lets say we are logged in as Admin and want to update it via JPA AdminUserInfoRepository. Is it appropriate to get the currently logged in user ID and then just create an entry in AdminUserInfo table and set the ID to the currently logged in user without creating a mapping between the two tables. If not, how should I map them?
Another way I think of doing it is when a user is created, an entry for it to be automatically created in the corresponding info table based on his role but I don't know how to do that

Use non standard types in Azure Easy Tables

I'm trying to use Azures Easy Tables in my Xamarin Application.
I have data in 2 tables in azure which i added through csv. These tables include only standard types like string, date and numbers and are correctly synced to the device.
Additionally i have several other tables which are present in the local sync store. These tables / classes also use non standard types i defined myself. For example i habe a class Contact which has a property Company, which again is another class with several standard properties. These tables are currently only saved locally in the sync store, and it's working as expected. I'm now trying to sync these tables to to Azure Easy Tables.
So what i did was creating the table as an Azure Easy Table in Azure named Contact, with dynamic schema activated. When i try to Client.SyncContext.PushAsync() i get the following Exception:
MobileServiceLocalStoreException:
"Push operation has failed. See the PushResult for details."
Inner Exception / JsonReaderException:
"Failed to read errors from the local store."
Inner Exception / JsonException
"Unexpected character encountered while parsing value: C. Path '', line 0, position 0."
Push Result seems to provide no information (Error Count 0)
I have no idea what this Exception tells me. Maybe the problem has something to do with the properties being non standard? How are these properties even mapped to an easy table. Is a non-standard property like company simply split into several columns like Name, Street, City?
Or does the Exception point to some other problem with the local sync Store? As i said, the local syncstore is currently working fine and the pull from azure easy tables for some tables is also working fine.
I'm grateful for every answer that might point me in the right direction.
Per my understanding, you are handling 1:1 relationships between Contact and Company tables. For offline sync, you need to define the Contact and Company classes in your mobile client as follows:
For mobile client models
public class Contact : TableData
{
public string ContactName {get;set;}
public string Phone {get;set;}
public string Address {get;set;}
public string CompanyId {get;set;}
}
public class Company : TableData
{
public string CompanyName {get;set;}
public string Address {get;set;}
}
Note: As adrian hall's book Chapter3 :Relationships states about relationships on mobile client as follows:
There are a couple of rules you must follow within your client code:
You need to ensure that you create a Company before associating that Company with a Contact.
You need to store the CompanyId with the Contact, not the Company object (as you would normally do within Entity Framework).
If you InsertAsync a Company in offline mode, it will be placed into the operations queue prior to anything that uses it. Since the operations queue is processed in order, the Company will be sent to the backend prior to any record updates that would use it.
For Azure Easy Tables, you need to create both Contact and Company tables, and it would automatically create the Node.js backend for your created tables.
I would prefer handling tables individually and handling relationship management on the mobile client manually which could make the server much simpler by avoiding most of the complexity of relationships. Additionally, you could refer to Chapter 3 - Data Access and Offline Sync.

In Yii how to show data of two table

I have two table
User
---------
id
username
password
level
company_id
Company
-----------
id
name
website
Now I want to show user list(Gridview) with their company name WHERE company_id = 1
You must use relations in your models. After creating your models via gii go to your User model and change relations method like below:
public function relations() {
return array(
'company'=>array(self::HAS_ONE,'Company','company_id')
);
}
Then, you can do like below:
$user=User::model()->findByPk(10); //for example user with id=10
echo $user->company->name; //it returns the relative company name
Notes:
I assumed that each user has one company. That's why I wrote self::HAS_ONE
In CGridView you can do : $data->company->name
company is just a name for relation, but the Company is the related model
Yii has a powerful and comprehensive document. So, it is better to take a look at its official document. Relational Query Options

Read from table, infer counter and insert on database using entity framework 5 and mvc 4

I have this situation. I have a table called Request. This table has a column named Number. Every time I want to insert a new Request then I fetch the last request and based on its Request Number I infer a new one.
For example, I have on my database Request1 with number 0001 then when I will insert a new one I fetch Request1 and based on its Number I infer my new Request Number which should be 0002.
The problem occurs when I want to create two Requests simultaneously. Process one fetch the Request1 and process two also gets Request1. When process one infers the new request number, which should be 0001, process two do the same. At the end I will create two new requests with the same Number.
Someone knows how to solve this?
Sorry about my english! ;)
There are several ways to solve your problem.
The field is always numeric, sequential, and each record the value must be higher than the last record?
If it is, you simply let the database do the work for you. Just set the field in question as the primary key of the table and how identity. In this case the database will provide the solution to internal competition, and of course to prevent ending up getting duplicate records. And the number is automatically filled by the DBMS (SQL Server, MySQL, Oracle ...)
If you are using EntityFramework and Code First, just go in the declaration of the entity (a C # class that defines the table in the database) and locate the field you need and add 2 attributes to him:
// Probably you have this kind of code (which fieldID should be the field name)
public Int32 fieldID {get; set;}
// Just add these two attributes before the declaration of the field
[Key]
[DatabaseGenerated (DatabaseGeneratedOption.Identity)]
public Int32 fieldID {get; set;}
/* Example in C#, assuming you are using SQL Server and EFCF */
/* EF CF means Entity Framework Code First! */
You need to implement a logic to populate this field, which may not be as described above, or the field is not numeric or can not be done by the database and have to be direct by your application?
You can implement a lock on straightforward piece of code that can not have competition.
In the class that makes the manipulation of data and you are encountering the problem declare a variable of type Object, static and read-only like this:
private static readonly Object concurrencyLock = new Object ();
In the method that implements the logic that needs to be accessed uniquely enclose the code with a lock policy
lock(concurrencyLock) {
//Do stuff here without concurrency
/* When the current request into this part of the code,
any other request will execute until the line above with "lock" statement.
Until this current request exit this "lock" block of code,
the other(s) will wait. As this one leave this block, one other join...
One at a time as you wish. */
}
There are others ways to do that too, but is a bit more complex or dosen't work well in a Web Application (like a Mutex, that would work fine if it's a Windows Service, ou Windows Form application)

How to retrieve system attributes of account entity using IOrganisationservice ,.retrieve method

I have a requirement where I need to retrieve the system attributes of an entity.
ColumnSet cset = new ColumnSet(true);
cset.AllColumns = true;
Entity capconnect=(Entity)_servicecapconnect.Retrieve("account",cc.Key,cset);
When I do retrieve the entity capconnect has only the custom attributes of account.But I am interested in getting attributes like "telephone1" "address1_line1" which are system attributes of account entity.
I looked in the database the account entity has 60 columns but the attributes retrieved are only 46 which are all the custom attributes.
I appreciate your inputs.
-Akila
I assume that the properties, which are not present in the entity, don't have a value. This is normal as the response will only include the fields which contain values due to performance reasons.
Therefore the response won't be bloated with null values.