How to use a Snowflake-Schema in Mondrian? - schema

I have a fact table that has a RESOURCE_ID that links to the resource table. A resource has a role, that it self is a resource.
.--FACTTABLE--.
| IDENTIFIER | .--RESOURCE---.
| RESOURCE_ID |----| RESOURCE_ID | .--RESOURCE---.
| ROLE_ID |----| RESOURCE_ID |
| TITLE |
Now i want to create a dimension ROLE that contains the attribute TITLE.
How to do this? Example with Mondrian 4 Schema would be appreciated.
I know there is a <Link> for the <PhysicalSchema> and the <ForeignKeyLink> for the <DimensionLinks> but i don't know how to use them properly.

Okay i found out how to do this.
Solve cycles
Since role and resource are both from the table RESOURCE, Mondrian couldn't handle that and came into a cycle.
I solved this with an alias for the RESOURCE table:
<Table name="resource" schema="public" keyColumn="id" alias="role"/>
Link tables
To let Mondrian know which resource belongs to which role, you need to link both tables.
Therefor it's important that the resource table has a key:
<Table name="resource" schema="public" keyColumn="id"/>
Now you can link the resource to it's role:
<Link target='resource' source='role' foreignKeyColumn='role_id'/>
Define the dimension
The confusing thing at first, is that the role dimension needs the table resource. That's because the fact table only knows the RESOURCE_ID and not the ROLE_ID. But since every resource is linked to it's role, you can use the Attributes to define the role specific fields.
<Dimension name="Role" table="resource" key="ID">
<Attributes>
<Attribute name="ID" keyColumn="id" hasHierarchy="false"/>
<Attribute name="Title" table="role" keyColumn="title"/>
</Attributes>
</Dimension>
Use the dimension
To use the dimension we have to use the dimension in the cubes dimensions and link the RESOURCE_ID of the fact table to the role dimension.
Useage:
<Dimension source="Role"/>
DimensionLinks:
<ForeignKeyLink dimension="Role" foreignKeyColumn="resource_id"/>

Related

Liquibase check constraint between two tables

I want to create two new columns each one of them is in a different table.
For example: on company table i want to create a column with name last_registration_number and the second column called registration_number on employee table with check constraint that follows this logic
registration_number of employee table <= last_registration_number of company table
I couldn't found how to do this between two tables.
What is the proper way to do this?
I suppose Liquibase PRO version could help. It has addCheckConstraint tag (as well as edit and drop). Here's a link to the description.
Also there's a checkConstraint attribute in constraints tag:
<createTable tableName="foo">
<column name="bar" type"integer">
<constraints checkConstraint="your condition here"/>
</column>
</createTable>
but I'm not sure if it'll work, since the pull request basics of implementing checkConstraint is still open.
Or if you can just play around with sql tag which allows you to do anything you want in plain SQL.

Authenticating users with Spring security against two user-services

I am very new to Spring security and my problem is as follows:
I have a member mysql table that contains information about the website's members, including their usernames, passwords and roles. So far so good: I can use this table to configure a <jdbc-user-service.
However I also want to have a super user that is not going to be in the member table.
Is it possible and recommended to have this super-user in an in-memory user repository and therefore mix jdbc user service with in-memory user service? If so how?
If 1. is not possible perhaps I can have a second mysql table called for instance moderator. Then what sort of sql query would I need to authenticate against these two tables?
Collissions
The problem with multiple repositories is that you need to ensure that you differentiate which user is which. For example assume your data looks like the following
member table
username
----------------------
member
moderator table
username
----------------------
moderator
Then you have some data associated to your users
data table
username value
----------------------------------------
moderator secret
What now happens if you get a collision? For example, a user signs up and your member table now looks like this:
member table
username
----------------------
member
moderator
Which moderator owns the data? There is no way to distinguish between the two users.
Alternative Approach
The alternative approach would be to use a mapping of users to roles. It would be to use something like this:
member table
username is_moderator
----------------------
member false
moderator true
Then when a user tries to sign up for with an existing username, there is a constraint violation so you do not need to differentiate between the two. Of course you could map the roles using another table. This is what Spring Security does normally using the authorities table.
Using multiple UserDetailsService
If you really want to use multiple user repositories anyways, you can simply declare multiple UserDetailsService entries in your configuration. An in memory configuration example is shown below:
<authentication-manager>
<authentication-provider>
<jdbc-user-service .. />
</authentication-provider>
<authentication-provider>
<user-service>
<user username="moderator"
password="password"
authorities="ROLE_MODERATOR"/>
</user-service>
</authentication-provider>
</authentication-manager>
If you want to do both in the database, you need to determine what your SQL queries for each table are and then add two elements. For example:
<authentication-manager>
<authentication-provider>
<jdbc-user-service .. />
</authentication-provider>
<authentication-provider>
<jdbc-user-service .. />
</authentication-provider>
</authentication-manager>
Use the attributes to control your sql queries. You can refer to the Spring Security appendix for example queries.

NHibernate HiLo generation and SQL 2005/8 Schemas

I have an issue on my hands that I've spent several days searching for an answer to no avail...
We're using HiLo Id generation, and everything seems to be working fine, as long as the entity table is in the same schema as the hibernate_unique_key table.
The table structure is pretty simple. I have my hi value table in the db as dbo.hibernate_unique_key. Several entity table are also in the dbo schema, and they work without issue. Then we have tables under the "Contact" schema (such as Contact.Person and Contact.Address).
In the Person Mapping file:
<class name="Person" table="Person" schema="Contact">
<id name="Id" unsaved-value="0">
<generator class="hilo">
<param name="max_lo">100</param>
</generator>
</id>
...
When I try to insert a Person entity, I get an error of "Invalid object name 'Contact.hibernate_unique_key'. That error is certainly clear enough. So I add:
<param name="schema">dbo</param>
to my mapping file/generator element. Now, when the SessionFactory is built, I get a "An item with the same key has already been added." error. So now I'm a bit stuck. I can't leave the HiLo generator without a schema, because it picks up the schema from the Class, and I can't specify the schema because it's already been added (presumably because it's my "default_schema" as identified in my XML cfg file).
Am I completely hosed here? Must I either
A) Keep all my tables in the dbo schema or
B) Create a separate HiLo Key table for each unique schema in the DB?
Neither of those scenarios is particularly palatable for my application, so I'm hoping that I can "fix" my mapping files to address this issue.
Only one such table per database should exist. Such data table should imply the following columns (let's call this table Parameters):
HiLoId
TableName
ParamName
HiLoAssigned
In addition to be used as a HiLo assignment data table, this could be used as a parameter table. As such, the ParamName field is required. This could contain data such as:
HiLoId | TableName | ParamName | HiLoAssigned
---------------------------------------------
1 | Parameters| HiLoId | 3
2 | Customers | CustomerId| 9425
3 | Invoices | InvoiceId | 134978
And when you need some other parameters, such as a parameter for a job that would prune your tables for history, then an age parameter for record could be inserted into it.
Well, I'm a little further in the subject than what you actually asked. Just sharing some additional thoughts in database design/architecture.
Take an eye out this question, and see my answer there. This might answer your question as well, and bring further information to this answer.
Have you tried specifying the schema with the table name on all generators (including the ones already in the dbo schema? I.e.
<param name="table">dbo.hibernate_unique_key</param>
The hilo generator looks for a '.' in the table name, and qualifies it (with schema) only if one isn't there.
I don't think there's anything wrong with solution B. Behavior will be pretty much the same.

How to automatically delete many-to-many associations (cascade)

In my database I've got Users and UserGroups which have a many-to-many relation. The User has a set of UserGroup, the UserGroup domain object does not see the User.
<class name="User" table="UserTable">
<set name="UserGroup" cascade="save-update" access="field.pascalcase-underscore" table="User2UserGroup">
<key column="User_Id" />
<many-to-many class="UserGroup" column="UserGroup_Id" />
</set>
...
What I'm trying to achieve is the nhibernate deleting the correlation from the junction table when I delete either a User or a User Group. Additionally User and Group are child objects of, let's call it a Domain. Domain does cascade="all-delete-orphans", so when a Domain gets deleted it cascade-deletes all its Users and UserGroups.
Back to the User<->UserGroup relation: If I understand correctly I can't use any form of cascade that involves delete as I just want to delete the association between two objects and not the related object itself. (A group shall not vanish, even if it's an orphan. And a User without a group is a valid thing in my world - he just has no rights to do anything at all.)
Do I need to look at events/interceptors? Or can I do what I want to achieve by controlling the mapping?
If you are using a database that supports it can you not set the cascade on the database itself in the form of a Foreign Key constraint?

How to map many to many association in NHibernate

I have some database tables named Project, Employee and Branch. An employee can work simultaneously on more than one project. Similarly, in a project, there are multiple employees. Also, a project is conducted at a particular branch. To maintain all these relationships, I am using a project_employee_branch table, which will store the related primary keys of the above three tables. As an example, this project_employee_branch table may contain a row like (1,2,3), which means the project whose primary key is 1, is conducted at branch whose primary key is 3, and one of its project member is an employee whose primary key is 2.
How can I map all these associations in NHibernate? I have mapped many-to-one association using foreign key concept, but I don't know how to map these types of associations, where an intermediate table is involved.
First point I'd make is that your database schema and your description don't match, so please take any advice below in the light of that initial caveat. You say that
a project is conducted at a particular branch
which implies there should be a simple foreign key relationship from project to branch. And of course, if this is what the schema looked like, you would have a two-way many-to-many link table and your life would be much easier.
Anyway, with the three-way combination you have, you need to have a collection of components, where the components have many-to-one properties for the other two object types. There is an example in section 7.2 of the NHibernate documentation, but I think it would look something like this in the mapping for Product:
<set name="BranchEmployees" table="product_employee_branch" lazy="true">
<key column="product_id">
<composite-element class="Purchase">
<many-to-one name="Branch" class="Branch" />
<many-to-one name="Employee" class="Employee"/>
</composite-element>
</set>