views:

38

answers:

2

I'm sure this is a question to which most of the answers will be "Why are you doing that?", but I thought I would ask.

I've got a table of (Users), the vast majority of which just have an ID (as they're lazily created users for sessions that have never provided any information), and don't use the rest of the columns in the database. I've decided to just remove these rows in order to save space in the database. There are loads of tables with foreign keys to the table, but only two or three that can reference these fake users.

For a lot of these tables I've just switched the mapping to map the userid rather than the User object, but some objects would like to have the whole User object there if it exists in the table, and null otherwise.

CREATE TABLE users AS (userid bigint);
CREATE TABLE shopping_carts AS (cartid bigint, userid bigint);

I can't see how to map this in Hibernate.

@Entity
class User {
  @Id
  long id;
}

@Entity
class ShoppingCart {
 @Id
 long id;
 @Column("userid")
 long userid; // Might not correspond to a user.
 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn("userid", insertable = false, updateable = false, nullable = true)
 User user;
}

Now, this doesn't return a null, but throws an ObjectNotFoundException if the user_id points to a user that doesn't exist. Even if you add a @Fetch(FetchMode.JOIN). Is there any way to get it treated as null if it doesn't exist?

I've considered a couple of ways to do this:

  1. Add a LoadEventListener which returns special "null-objects" on any load of a User that didn't find anything (and a PreInsert/PreUpdateEventListener that vetos saving them).
  2. Adding a descriminator column to ShoppingCart and having a subclass which does have the User mapped, and one that doesn't then mapping that using single table inheritance.
  3. (edit) Map a ManyToMany collection of Users, which will be an empty collection in the case where it doesn't exist, and a collection with one id in the other case - will this work without a join table?

Any comments on these, or other ideas?

+1  A: 

Not sure how it looks in annotations, but in XML there is "not-found" parameter:

<many-to-one name="user" class="com.example.User" column="userid" not-found="ignore" />
serg
+1  A: 

From Hibernate Annotation Reference, you can do a

@ManyToOne
@NotFound(action=NotFoundAction.IGNORE)

to ignore the missing record.

rajasaur