I'm getting the following exception when saving an object:
Found shared references to a collection
Does anyone know what this means?
In theory it means that you have 2 records which contain the same reference to another object. At the database level this is most likely a weak entity, however at the code level this is likely to be represented as a collection.
Have you copied another records collection?
E.g.
Blog blog1 = Blog.Find(1);
Blog blog2 = new Blog();
blog2.Entries = blog1.Entries;
blog2.Save();
This code is for ActiveRecords, but as it is built on top of nHibernate the underlying principles are the same.
The interesting thing when i came across this issue was that the collection it referred to was incorrect. It was a different one.
If this is your issue try iterating through each item and assigning it to the new collection in stead. E.g.
Blog blog1 = Blog.Find(1);
Blog blog2 = new Blog();
foreach (BlogEntry entry in blog1.Entries)
blog2.Entries.Add(entry);
blog2.Save();
quick google says
rel Group n --- 1 User
m ^
| | inh
| rel |
--------- n Member
rel stands for relation (association)
inh stands for inheritance
The exception is thrown after Member
objects have successfully been created
and then have been read from the
database. After the last Member object
was read the transaction is committed
but this fails.
what do your mappings look like?
Do you have a reference to any of the objects in the collection somewhere else? Another session, possibly, or even within the same session in another object? Make sure that when you access hibernate, you are controlling the ONLY reference to those objects within any hibernate session.
From my experience, this error occurs when you have a joined-subclass mapping where an inherited property is mapped in both the super- and sub-class. Say you have these objects:
public class Being
{
public string DnaSequence { get; protected set; }
}
public class Animal : Being
{
public IList<Animal> Relatives { get; protected set; }
}
public class Human : Animal
{
public string Name { get; protected set; }
}
In your Human mapping, it's important that you don't map the Relatives property. In a joined-subclass mapping, you should only map properties that are unique to the level in the hierarchy you are mapping:
For Being, you only map the DnaSequence property.
For Animal, you only map the Relatives property.
For Human, you only map the Name property.
If you, by accident, map Relatives in the Human mapping, NHibernate will throw "Found shared references to a collection".
Related
There's something that has been bothering from my DDD readings. From what I've seen, it seems as if there is only repository instance for each given aggregate root type in my system.
Consider, for instance, the following imaginary situation as an abstraction of a deeper domain model:
When coding in a "standard-style" I'd consider that each Owner in my system would have its own collection of cars, so there would be an equal number of Car collections (should I call it Repositories?) as there are Owners. But, as stated previously, it seems as if in DDD I should only have one CarRepository in the whole system (I've seen examples in which they are accessed as static classes), and to do simple operations such as adding cars to the Owner, I should make use of a domain-service, which seems to be, for the simple case, not very API friendly.
Am I right about only having one CarRepository instantiated in my system (Singleton), or am I missing something? I'd like to strive for something like
public void an_owner_has_cars() throws Exception {
Owner owner = new Owner(new OwnerId(1));
CarId carId = new CarId(1);
Car car = new Car(carId);
owner.addCar(car);
Assert.assertEquals(car, owner.getCarOf(carId));
}
but that doesn't seem to be possible without injecting a repository into Owner, something that seems to be kind of forbidden.
A repository does not represent a collection that belongs to another entity. The idea is that it represents the entire collection of entities.
So in your example Car is an entity and probably an aggregate. So your model is OK on a conceptual level but you need to split the tight coupling between Car and Owner since Owner is most definitely an AR and, in your current model, deleting it would mean all cars belonging to it should be deleted also.
What you are probably after is something like this:
public class Owner {
private IEnumerable<OwnedCar> cars;
}
public class OwnedCar {
public Guid CarId { get; set; }
}
Or, as an alternative to a VO:
public class Owner {
private IEnumerable<Guid> carsOwned;
}
So one AR should not reference another AR instance.
Another point is that you probably do not want to inject repositories into entities since that may indicate a bit of a design flaw (somewhat of a code smell).
To get the owned cars into the Owner would be the job of the OwnerRepository since it is part of the same aggregate. There would be no OwnedCarRepository since it is a value object.
100% for sure, you don't have to make a singleton CarRepository unless you're working in a legacy system which doesn't use any dependency inejction mechanism.
If you find you need to inject CarRepository to Owner to retrieve cars belong to a specific owner, maybe it's a hint that you should re-model there relationship like:
public class Owner {
}
public class Car {
private Owner owner;
}
And use CareRepository to achieve your goal:
public interface CarRepository {
List<Car> findBy(String onwer);
}
And just a speculation, the static part maybe refer to DomainEvents, like:
public class Owner {
public long quantityOfCarsOwned() {
return DomainEvents.raise(new SumCarsEvent(this));//static
}
}
public class SumCarsEventHandler {
private CarRepository carRepository;//inject this, SumCarsEventHandler should be a statless bean managed by container like spring
public long handle(SumCarsEvent event) {
return carRepository.countBy(event.getOwner());
}
}
In very simple case, it's just too complicated I think.
I am using Fluent nHibernate for my persistence layer in an ASP.NET MVC application, and I have come across a bit of a quandry.
I have a situation where I need to use an abstraction to store objects into a collection, in this situation, an interface is the most logical choice if you are looking at a pure C# perspective.
Basically, an object (Item) can have Requirements. A requirement can be many things. In a native C# situation, I would merely accomplish this with the following code.
interface IRequirement
{
// methods and properties neccessary for evaluation
}
class Item
{
virtual int Id { get; set; }
virtual IList<IRequirement> Requirements { get; set; }
}
A crude example. This works fine in native C# - however because the objects have to be stored in a database, it becomes a bit more complicated than that. Each object that implements IRequirement could be a completely different kind of object. Since nHibernate (or any other ORM that I have discovered) cannot really understand how to serialize an interface, I cannot think of, for the life of me, how to approach this scenario. I mean, I understand the problem.
This makes no sense to the database/orm. I understand completely why, too.
class SomeKindOfObject
{
virtual int Id { get; set; }
// ... some other methods relative to this base type
}
class OneRequirement : SomeKindOfObject, IRequirement
{
virtual string Name { get; set; }
// some more methods and properties
}
class AnotherKindOfObject
{
virtual int Id { get; set; }
// ... more methods and properties, different from SomeKindOfObject
}
class AnotherRequirement : AnotherKindOfObject, IRequirement
{
// yet more methods and properties relative to AnotherKindOfObject's intentive hierarchy
}
class OneRequirementMap : ClassMap<OneRequirement>
{
// etc
Table("OneRequirement");
}
class AnotherRequirementMap : ClassMap<AnotherRequirement>
{
//
Table("OtherRequirements");
}
class ItemMap : ClassMap<Item>
{
// ... Now we have a problem.
Map( x => x.Requirements ) // does not compute...
// additional mapping
}
So, does anyone have any ideas? I cannot seem to use generics, either, so making a basic Requirement<T> type seems out. I mean the code works and runs, but the ORM cannot grasp it. I realize what I am asking here is probably impossible, but all I can do is ask.
I would also like to add, I do not have much experience with nHibernate, only Fluent nHibernate, but I have been made aware that both communities are very good and so I am tagging this as both. But my mapping at present is 100% 'fluent'.
Edit
I actually discovered Programming to interfaces while mapping with Fluent NHibernate that touches on this a bit, but I'm still not sure it is applicable to my scenario. Any help is appreciated.
UPDATE (02/02/2011)
I'm adding this update in response to some of the answers posted, as my results are ... a little awkward.
Taking the advice, and doing more research, I've designed a basic interface.
interface IRequirement
{
// ... Same as it always was
}
and now I establish my class mapping..
class IRequirementMap : ClassMap<IRequirement>
{
public IRequirementMap()
{
Id( x => x.Id );
UseUnionSubclassForInheritanceMapping();
Table("Requirements");
}
}
And then I map something that implements it. This is where it gets very freaky.
class ObjectThatImplementsRequirementMap : ClassMap<ObjectThatImplementsRequirement>
{
ObjectThatImplementsRequirementMap()
{
Id(x => x.Id); // Yes, I am base-class mapping it.
// other properties
Table("ObjectImplementingRequirement");
}
}
class AnotherObjectThatHasRequirementMap : ClassMap<AnotherObjectThatHasRequirement>
{
AnotherObjectThatHasRequirementMap ()
{
Id(x => x.Id); // Yes, I am base-class mapping it.
// other properties
Table("AnotheObjectImplementingRequirement");
}
}
This is not what people have suggested, but it was my first approach. Though I did it because I got some very freaky results. Results that really make no sense to me.
It Actually Works... Sort Of
Running the following code yields unanticipated results.
// setup ISession
// setup Transaction
var requirements = new <IRequirement>
{
new ObjectThatImplementsRequirement
{
// properties, etc..
},
new AnotherObjectThatHasRequirement
{
// other properties.
}
}
// add to session.
// commit transaction.
// close writing block.
// setup new session
// setup new transaction
var requireables = session.Query<IRequirable>();
foreach(var requireable in requireables)
Console.WriteLine( requireable.Id );
Now things get freaky. I get the results...
1
1
This makes no sense to me. It shouldn't work. I can even query the individual properties of each object, and they have retained their type. Even if I run the insertion, close the application, then run the retrieval (so as to avoid the possibility of caching), they still have the right types. But the following does not work.
class SomethingThatHasRequireables
{
// ...
public virtual IList<IRequirement> Requirements { get; set; }
}
Trying to add to that collection fails (as I expect it to). Here is why I am confused.
If I can add to the generic IList<IRequirement> in my session, why not in an object?
How is nHibernate understanding the difference between two entities with the same Id,
if they are both mapped as the same kind of object, in one scenario, and not the other?
Can someone explain to me what in the world is going on here?
The suggested approach is to use SubclassMap<T>, however the problem with that is the number of identities, and the size of the table. I am concerned about scalability and performance if multiple objects (up to about 8) are referencing identities from one table. Can someone give me some insight on this one specifically?
Take a look at the chapter Inheritance mapping in the reference documentation. In the chapter Limitations you can see what's possible with which mapping strategy.
You've chose one of the "table per concrete class" strategies, as far as I can see. You may need <one-to-many> with inverse=true or <many-to-any> to map it.
If you want to avoid this, you need to map IRequirement as a base class into a table, then it is possible to have foreign keys to that table. Doing so you turn it into a "table per class-hierarchy" or "table per subclass" mapping. This is of course not possible if another base class is already mapped. E.g. SomeKindOfObject.
Edit: some more information about <one-to-many> with inverse=true and <many-to-any>.
When you use <one-to-many>, the foreign key is actually in the requirement tables pointing back to the Item. This works well so far, NH unions all the requirement tables to find all the items in the list. Inverse is required because it forces you to have a reference from the requirement to the Item, which is used by NH to build the foreign key.
<many-to-any> is even more flexible. It stores the list in an additional link table. This table has three columns:
the foreign key to the Item,
the name of the actual requirement type (.NET type or entity name)
and the primary key of the requirement (which can't be a foreign key, because it could point to different tables).
When NH reads this table, it knows from the type information (and the corresponding requirement mapping) in which other tables the requirements are. This is how any-types work.
That it is actually a many-to-many relation shouldn't bother you, it only means that it stores the relation in an additional table which is technically able to link a requirement to more then one item.
Edit 2: freaky results:
You mapped 3 tables: IRequirement, ObjectThatImplementsRequirement, AnotherObjectThatHasRequirement. They are all completely independent. You are still on "table per concrete class with implicit polymorphism". You just added another table with containing IRequirements, which may also result in some ambiguity when NH tries to find the correct table.
Of course you get 1, 1 as result. The have independent tables and therefore independent ids which both start with 1.
The part that works: NHibernate is able to find all the objects implementing an interface in the whole database when you query for it. Try session.CreateQuery("from object") and you get the whole database.
The part that doesn't work: On the other side, you can't get an object just by id and interface or object. So session.Get<object>(1) doesn't work, because there are many objects with id 1. The same problem is with the list. And there are some more problems there, for instance the fact that with implicit polymorphism, there is no foreign key specified which points from every type implementing IRequirement to the Item.
The any types: This is where the any type mapping comes in. Any types are stored with additional type information in the database and that's done by the <many-to-any> mapping which stores the foreign key and type information in an additional table. With this additional type information NH is able to find the table where the record is stored in.
The freaky results: Consider that NH needs to find both ways, from the object to a single table and from the record to a single class. So be careful when mapping both the interface and the concrete classes independently. It could happen that NH uses one or the other table depending on which way you access the data. This may have been the cause or your freaky results.
The other solution: Using any of the other inheritance mapping strategies, you define a single table where NH can start reading and finding the type.
The Id Scope: If you are using Int32 as id, you can create 1 record each second for 68 years until you run out of ids. If this is not enough, just switch to long, you'll get ... probably more then the database is able to store in the next few thousand years...
I have document scanning system where several types of documents are scanned. Initially, the document has no information when its scanned, then they get classified and additional information is entered for them in a second step later. So, I have a base class called Document, and subclasses for each type with their respective metadata like below. I have it setup as a table-per-subclass (joined subclass) mapping in NHibernate.
public class Document
{
public int ID { get; set; }
public string FilePath { get; set; }
}
public class Certificate : Document
{
// certificate-specific fields
}
public class Correspondence : Document
{
// correspondence-specific fields
}
What I need to be able to do is create a Document class first and save it. Then retrieve in a second step later on and convert it to one of the subclass types and fill in the rest of its information. What would be the best approach to do this, and is this even possible with NHibernate? If at all possible I would like to retain the original document record, but its not a dealbreaker if I have to jettison it.
Unfortunately, NHibernate does not allow you to switch between subclasses after initial creation; to get this working the way you want, you have 3 options:
Use a native sql call to change the discriminator (and possibly) add or change any subclass-related fields.
Copy the contents of your object to a new object of the proper class and then delete the original.
Don't use subclasses, control the state of your object through an enumeration or some other mechanism that allows you to determine their type at run-time.
This issue has already been discussed here. I would go with Terry Wilcox's tip to use a role for this. Composition over inheritance.
Supposing the following entities :
public class AppUser
{
public virtual int Id { get; set; }
public virtual string Login { get; set; }
}
// Mapped as joined-subclass
public class Person : AppUser
{
public virtual int Age { get; set; }
}
If I create 1 AppUser, and save it like this
var user = new AppUser() { Login = "test" };
session.Save( user ); // let's say Id = 1
How can I cast/convert/"promote" it to a Person, keeping the same ID ?
Now, i'm stuck with a row in my AppUser table, with Id = N. How can I populate the Person table with the same Id ? I can't delete the AppUser and recreate it as a Person, as AppUser may be referenced by foreign keys.
I could issue a "manual" SQL INSERT, but it's kind of ugly...
This is definitively a NHibernate question. I understand that from an OOP point of view, this makes little sense, hence the absence of other tags than nhibernate.
I don't believe nHibernate is going to be able to solve this problem for you. nHibernate is dealing with your data as an object and, especially with joined-subclass I don't believe there is anything built in that allows you to change the subclass type on the fly, or at least change the type and retain the original ID.
I think your best bet is to write a stored procedure that, given an ID and a NEW type, removes all entries from subclass tables and adds a new entry to the correct subclass table.
Once that proc runs, then reload the object in nHibernate (and make sure you have thrown away any cached data relating to it), it should now be of the correct type you want to work with, set its NEW properties and save it.
That way you have a relatively generic stored proc that just changes your subclass types, but you dont need to add all the crazy logic to handle various properties on your subclasses.
This has been discussed on SO before and I am quoting Jon Skeet for posterity:
No. A reference to a derived class
must actually refer to an instance of
the derived class (or null). Otherwise
how would you expect it to behave?
For example:
object o = new object();
string s = (string) o;
int i = s.Length; // What can this sensibly do?
If you want to be able to convert an
instance of the base type to the
derived type, I suggest you write a
method to create an appropriate
derived type instance. Or look at your
inheritance tree again and try to
redesign so that you don't need to do
this in the first place.
In Skeet's example, string's are objects and objects are not strings. So the "upcasting" would not work.
I have a following mapping:
<set name="People" lazy="true" table="ProjectPeople">
<key column="ProjectId" />
<composite-element class="PersonRole">
<many-to-one name="Person" column="PersonId" cascade="save-update" not-null="true" />
<many-to-one name="Role" column="RoleId" cascade="save-update" not-null="true" />
</composite-element>
</set>
Now, I do not really want to have a separate class for Role in domain, I need only the Role name. However, in DB Roles should still be normalized to a separate table Role (Id, Name).
How do I map it so that People use following PersonRole class?
public class PersonRole {
public virtual Person Person { get; set; }
public virtual string Role { get; set; }
}
Update: added bounty, seems like a question useful not only to me.
You won't actually get the answer you hope for, simply because it is not possible. (N)Hibernate is an Object-Relational-Mapping framework and support three kinds of mapping strategies:
table per class hierarchy
table per subclass
table per concrete class
It also allows you to deviate from this by using formula or sql-insert etc, but as you've found out, these only cause you more pain in the end, are not encouraged by the Hibernate community and are bad for the maintainability of your code.
Solution?
Actually, it is very simple. You do not want to use a class for Role. I assume you mean that you do not want to expose a class of type Role and that you do not want to have to type prObject.Role.Name all the time. Just prObject.Role, which should return a string. You have several options:
Use an inner class in, say, PersonRole, this class can be internal or private. Add a property Role that sets and updates a member field;
Use an internal class. Add a property Role that sets and updates a member field;
Let's examine option 2:
// mapped to table Role, will not be visible to users of your DAL
// class can't be private, it's on namespace level, it can when it's an inner class
internal class Role
{
// typical mapping, need not be internal/protected when class is internal
// cannot be private, because then virtual is not possible
internal virtual int Id { get; private set; }
internal virtual string Name { get; set; }
}
// the composite element
public class PersonRole
{
// mapped properties public
public virtual Person Person { get; set; }
// mapped properties hidden
internal virtual Role dbRole { get; set; }
// not mapped, but convenience property in your DAL
// for clarity, it is actually better to rename to something like RoleName
public string Role /* need not be virtual, but can be */
{
get
{
return this.dbRole.Name;
}
set
{
this.dbRole.Name = value; /* this works and triggers the cascade */
}
}
}
And the mapping can look as expected. Result: you have not violated the one-table-per-class rule (EDIT: asker says that he explicitly wants to violate that rule, and Hib supports it, which is correct), but you've hidden the objects from modification and access by using typical object oriented techniques. All NH features (cascade etc) still work as expected.
(N)Hibernate is all about this type of decisions: how to make a well thought-through and safe abstraction layer to your database without sacrificing clarity, brevity or maintainability or violating OO or ORM rules.
Update (after q. was closed)
Other excellent approaches I use a lot when dealing with this type of issue are:
Create your mappings normally (i.e., one-class-per-table, I know you don't like it, but it's for the best) and use extension methods:
// trivial general example
public static string GetFullName(this Person p)
{
return String.Format("{0} {1}", p.FirstName, p.LastName);
}
// gettor / settor for role.name
public static string GetRoleName(this PersonRole pr)
{
return pr.Role == null ? "" : pr.Role.Name;
}
public static SetRoleName(this PersonRole pr, string name)
{
pr.Role = (pr.Role ?? new Role());
pr.Role.Name = name;
}
Create your mappings normally but use partial classes, which enable you to "decorate" your class any which way you like. The advantage: if you use generated mapping of your tables, you an regenerate as often as you wish. Of course, the partial classes should go in separate files so considering your wish for diminishing "bloat" this probably isn't a good scenario currently.
public partial class PersonRole
{
public string Role {...}
}
Perhaps simplest: just overload ToString() for Role, which makes it suitable for use in String.Format and friends, but of course doesn't make it assignable. By default, each entity class or POCO should have a ToString() overload anyway.
Though it is possible to do this with NHibernate directly, the q. has been closed before I had time to look at it (no ones fault, I just didn't have the time). I'll update if I find the time to do it through Hibernate HBM mapping, even though I don't agree to the approach. It is not good to wrestle with advanced concepts of Hib when the end result is less clear for other programmers and less clear overall (where did that table go? why isn't there a IDao abstraction for that table? See also NHibernate Best Practices and S#arp). However, the exercise is interesting nevertheless.
Considering the comments on "best practices": in typical situations, it shouldn't be only "one class per table", but also one IDaoXXX, one DaoConcreteXXX and one GetDaoXXX for each table, where you use class/interface hierarchy to differentiate between read-only and read/write tables. That's a minimum of four classes/lines of code per table. This is typically auto-generated but gives a very clear access layer (dao) to your data layer (dal). The data layer is best kept as spartan as possible. Nothing of these "best practices" prevent you using extension methods or partial methods for moving Role.Name into Role.
These are best general practices. It's not always possible or feasible or even necessary in certain special or typical sitations.
Personally I would create a Role class like Yassir
But If you want to use the structure that you have at the moment then create a view that contains the foriegn Key to your Person Table and the Role Description.
Modify the Set mapping table to point at your new view
Then modify your Role mapping so that it is a property instead of the many to one mapping.
However taking this approach I think will mean that you will not be able to update your role as it is reerencing a view.
Edit: To update the role you could add <sql-insert>,<sql-update> and <sql-delete> to your mapping file so that the cascade-all will work
i don't think it is possible to map many-to-one to a primitive type if i were you i would add a Role class to the model
This the biggest turn off of the whole OO purist thing.
Surely the goal is to have a working application. Not somebodies version of a perfect class hierarchy. So what if you have to code "prObject.Role.Name " instead of "prObject.Role". How does this help you make a better more reliable program?
From the application design purist point of view what you want is just plain wrong. A person can have several roles, a role can usually be assigned to several people.
Why go to all this trouble to enforce an unrealistic one role per person class hierachy when the undelaying data model is many roles per person?
If you really do have an "only one role per person" rule then it should be refleced in the underlying data model.