#ManyToMany mapping in JPA throws Exception [EclipseLink-6076] - eclipselink

I have developed simple JPA2.1 application with Oracle 11g database using Eclipse 2.5.2. Following is my scenario - there are two entities with #ManyToMany relation
Club
People
Club.java
#Entity(name = "CLUB")
public class Club {
#Id
private int c_id;
private String c_name;
#ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE},
fetch=FetchType.EAGER)
#JoinTable(name = "CLUB_PEOPLE",
joinColumns=#JoinColumn(name="c_id", referencedColumnName="c_id"),
inverseJoinColumns=#JoinColumn(name="p_id"))
private Set<People> people=new HashSet<People>();
public int getC_id() {
return c_id;
}
public void setC_id(int c_id) {
this.c_id = c_id;
}
public String getC_name() {
return c_name;
}
public void setC_name(String c_name) {
this.c_name = c_name;
}
public Set<People> getPeople() {
return people;
}
public void setPeople(Set<People> people) {
this.people = people;
}
public void addPeople(People p){
getPeople().add(p);
}
}
People.Java
#Entity(name="people")
public class People{
#Id
private int p_id;
private String name ;
#ManyToMany(mappedBy="people")
private Set<Club> club;
public int getP_id() {
return p_id;
}
public void setP_id(int p_id) {
this.p_id = p_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Client.java
public class Client1 {
public static void main(String[] args) {
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("JPA-Query");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Club> cq = cb.createQuery(Club.class).distinct(true);
Root<Club> root = cq.from(Club.class);
final List<Predicate> requiredCriteria = new ArrayList<Predicate>();
final Join people = root.join("people", JoinType.LEFT);
requiredCriteria.add(cb.or(cb.isNull(people)));
requiredCriteria.add(cb.isNull(people.get("name")));
requiredCriteria.add(cb.equal(people.get("name"), "people1"));
TypedQuery<Club> q = em.createQuery(
cq.where(cb.or(requiredCriteria
.toArray(new Predicate[requiredCriteria.size()])
))
);
List<Club> allemps = q.getResultList();
em.close();
emf.close();
}
}
Tables -
CREATE TABLE Club(
c_id number NOT NULL,
c_name VARCHAR2(20)
)
ALTER TABLE Club ADD CONSTRAINT CLUGGRPPK PRIMARY KEY (c_id);
CREATE TABLE People(
p_id number NOT NULL,
name VARCHAR2(20)
)
ALTER TABLE People ADD CONSTRAINT PEOPLEGRPPK PRIMARY KEY (p_id);
CREATE TABLE CLUB_PEOPLE
(
C_ID number,
P_ID number,
CONSTRAINT CLUB_PEOPLEPK PRIMARY KEY (C_ID, P_ID),
CONSTRAINT GROUP_FK FOREIGN KEY("C_ID")
REFERENCES "CLUB"("C_ID") ON DELETE CASCADE,
CONSTRAINT PEOPLE_FK FOREIGN KEY("P_ID")
REFERENCES "PEOPLE"("P_ID") ON DELETE CASCADE
)
When I run my Client.java it throws following exception
Exception Description: Object comparisons can only be used with OneToOneMappings. Other mapping comparisons must be done through query keys or direct attribute level comparisons.
Mapping: [org.eclipse.persistence.mappings.ManyToManyMapping[people]]
Expression: [
Query Key people
Base ManyToMany.Club]
Query: ReadAllQuery(referenceClass=Club )
javax.persistence.PersistenceException: Exception [EclipseLink-6076] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.QueryException
Exception Description: Object comparisons can only be used with OneToOneMappings. Other mapping comparisons must be done through query keys or direct attribute level comparisons.
Mapping: [org.eclipse.persistence.mappings.ManyToManyMapping[people]]
Expression: [
Query Key people
Base ManyToMany.Club]
Query: ReadAllQuery(referenceClass=Club )
at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:480)
at ManyToMany.Client.main(Client.java:75)
Caused by: Exception [EclipseLink-6076] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.QueryException
Exception Description: Object comparisons can only be used with OneToOneMappings. Other mapping comparisons must be done through query keys or direct attribute level comparisons.
Mapping: [org.eclipse.persistence.mappings.ManyToManyMapping[people]]
Expression: [
Query Key people
Base ManyToMany.Club]
Query: ReadAllQuery(referenceClass=Club )
at org.eclipse.persistence.exceptions.QueryException.unsupportedMappingForObjectComparison(QueryException.java:1170)
Please help me to solve above issue. Thanks in advance.

Related

Codec not found for requested operation: [list<varchar> <-> java.nio.HeapByteBuffer]

I am having an issue with storing data to Cassandra table from apache ignite when I am trying to insert into a column of list data type in Cassandra
Cassandra table:
CREATE TABLE business_categories (
id int,
category_name TEXT,
sub_categories list<TEXT>,
PRIMARY KEY(category_name, id)
);
xml file:
<persistence keyspace="ignite" table="business_categories">
<keyspaceOptions>
REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 1}
AND DURABLE_WRITES = true
</keyspaceOptions>
<tableOption>
comment = 'Cache test'
AND read_repair_chance = 0.2
</tableOption>
<keyPersistence class="com.cache.business.model.BusinessCategoriesKey" strategy="POJO"/>
<valuePersistence class="com.cache.business.model.BusinessCategoriesValue" strategy="POJO"/>
</persistence>
key class object:
public class BusinessCategoriesKey implements Serializable {
private static final long serialVersionUID = 581472167344584014L;
private int id;
private String category_name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCategory_name() {
return category_name;
}
public void setCategory_name(String category_name) {
this.category_name = category_name;
}
}
value class object:
public class BusinessCategoriesValue implements Serializable {
private static final long serialVersionUID = -1694694702874919854L;
private List<String> sub_categories = new ArrayList<>();
public List<String> getSub_categories() {
return sub_categories;
}
public void setSub_categories(List<String> sub_categories) {
this.sub_categories = sub_categories;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
}
I am getting the below error message
Caused by: com.datastax.driver.core.exceptions.CodecNotFoundException: Codec not found for requested operation: [list <-> java.nio.HeapByteBuffer]
The sub_categories field is a java.util.List and it seems Apache Ignite does not provide a direct mapping to appropriate Cassandra type for such kind of Java types.
So, this field could be persisted into Cassandra only if you manually specify all mapping details for the object type and if field type itself is implementing java.io.Serializable interface.
In such case, the field will be persisted into a separate table column as a blob.
Please try to modify your code in the following way:
CREATE TABLE business_categories (
id int,
category_name text
sub_categories blob,
PRIMARY KEY(category_name, id)
);
Persistence descriptor:
<persistence keyspace="ignite" table="business_categories">
<keyspaceOptions>
REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 1}
AND DURABLE_WRITES = true
</keyspaceOptions>
<tableOption>
comment = 'Cache test'
AND read_repair_chance = 0.2
</tableOption>
<keyPersistence class="com.cache.business.model.BusinessCategoriesKey" strategy="POJO"/>
<valuePersistence class="com.cache.business.model.BusinessCategoriesValue"
strategy="POJO"
serializer="org.apache.ignite.cache.store.cassandra.serializer.JavaSerializer">
<field name="sub_categories" column="sub_categories"/>
</valuePersistence>
You can find additional details here: Cassandra Integration Examples

Spring Data Rest Left Outer Join non-Entity POJO Null Entity Error

How do i accomplish getting the this interface method to work? i am using a MySQL DB if that matters...
public interface PersonRoleRepository extends CrudRepository<PersonRole,Long>{
//This causes null entity error from hibernate even though the SQL works outside hibernate
#Query(value="select * from Role r left outer join Person_Role pr on r.id = pr.role_id and pr.person_id = ? order by pr.expires_date desc", nativeQuery = true)
List<PersonRoleDto> getAllRolesAndPersonsStatusWithEachRole(int personId);
}
Here is the SQL query that returns what i want in SQL Workbench...
Select r.*, pr.*
from
Role r
left outer join person_role pr on r.id = pr.role_id and pr.person_id = ?
order by pr.expires_date desc;
Important MySQL database structure...
Table: Role
role_id bigint
name varchar
description varchar
...
Table: Person
person_id bigint
first_name varchar
last_name varchar
...
Table Person_Role_Link
person_role_id bigint
role_id bigint
person_id bigint
...
alter table person_Role_Link add constraint l1 foreign key (person_id) references Person(person_id)
alter table person_Role_Link add constraint l2 foreign key (role_id) references Role(role_id)
Here is the entity info...
#Entity
#Table(name="Role")
#EntityListeners(AuditEntityListener.class)
public class Role extends AbstractAuditEntity {
private static final long serialVersionUID= 44543543543543454543543L;
#id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="role_id")
private long id;
#NotNull
private String fullName
...
#OneToMany(mappedBy="role",cascade=CascadeType.ALL)
private Set<PersonRole> personRoles = new HashSet<>();
...
}
#Entity
#Table(name="Person_Role_Link")
#EntityListeners(AuditEntityListener.class)
class PersonRole extends AbstractAuditEntry{
private static final long serialVersion = 54324243242432423L;
#id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="person_role_id")
private long id;
#ManyToOne
#JoinColumn(name="person_id")
private Person person;
#ManyToOne
#JoinColumn(name="role_id")
private Role role;
...
}
#Entity
#Table(name="Person")
#EntityListeners(AuditEntityListener.class)
public class Person extends AbstractAuditEntity{
private ... serialVersionUID...;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="person_id")
private Long id;
...
#OneToMany(mappedBy="person", cascade=CascadeType.ALL)
private Set<PersonRole> personRoles = new HashSet<>();
...
}
Just for now i made a simple interface...
public interface PersonRoleDto {
String getFullName();
String getDescription();
//i want more attributes but for now i will just see if it works with the basics
}
Here is the latest HQL i tried...
public interface PersonRoleRepository extends CrudRepository<PersonRole,Long>{
//PersistentEntity must not be null
#Query("select r.fullName as fullName, r.description as description from Role r left join r.personRoles pr where pr.person = :person")
List<PersonRoleDto> findAllRolesWithPersonsStatus(#Param("person") Person person);
...
}
Whether I use HQL or native SQL i get a null entity error from hibernate. Also, the SQL generated from the HQL works without error but i still get a null entity error in code and, second, the SQL generated from HQL is slightly off which makes the results off. That's why i was trying so hard to get the native SQL to work.
The relationship is used to figure out how many people are in a role and at other times what roles a person has. This is a circular relationship, i'd say. I work on an Intranet so i had to hand type everything. If there are any problems seen in my code other than with the stated native query as stated then it is most likely because i had to hand type everything and not because the code is buggy. Everything else works so far but this one thing.
All help is appreciated.
UPDATE!!!!
I think this is the answer to my problem but when i try it i still get the error: PersistentEntity must not be null!
Here is how i tried to set it up...
//Added this to the top of PersonRole entity
#SqlResultSetMapping(
name="allRolesAndPersonsStatusWithEachRole"
classes={
#ConstructorResult(
targetClass=PersonRoleStatus.class,
columns={
#ColumnResult(name="full_name"),
#ColumnResult(name="description"),
...
}
)
}
)
#NamedNativeQuery(name="PersonRole.getAllRolesAndPersonsStatusWithEachRole",
query="Select r.*, pr.* from Role r Left Join person_role_link on r.role_id = pr.role_id and pr.person_id = :id", resultSetMapping="allRolesAndPersonsStatusWithEachRole")
Created my DTO like this...
public class RolePersonStatus {
private String fullName;
private String description;
private String ...
public RolePersonStatus(String fullName, String description, ...){
this.fullName = fullName;
this.description = description;
...
}
}
In my repository i just have:
//No annotation because it stated that the name of the method just needed to match the native query name?!?!?
List<RolePersonStatus> findAllRolesWithPersonStatus(#Param("id" Long id);
What am i missing???????
Try this way:
Entities
#Entity
#Table(name = "parents")
public class Parent {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
#OneToMany
private List<Child> children = new ArrayList<>();
//...
}
#Entity
#Table(name = "children")
public class Child {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
#ManyToOne(optional = false)
private Reference reference;
#OneToMany
private final List<Toy> toys = new ArrayList<>();
//...
}
#Entity
#Table(name = "references")
public class Reference {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String description;
//...
}
#Entity
#Table(name = "toys")
public class Toy {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
//...
}
DTO
public interface DemoDto {
String getParentName();
String getChildName();
String getToyName();
String getDescription();
}
Repository
public interface ParentRepo extends JpaRepository<Parent, Long> {
#Query("select " +
"p.name as parentName, " +
"c.name as childName, " +
"t.name as toyName, " +
"r.description as description " +
"from " +
"Parent p " +
"join p.children c " +
"join c.reference r " +
"join c.toys t " +
"where c.id = ?1 " +
"order by r.description desc")
List<DemoDto> getDto(Long childId);
}
Usage
#RunWith(SpringRunner.class)
#SpringBootTest
public class ParentRepoTest {
#Autowired
private ParentRepo parentRepo;
#Test
public void getDto() throws Exception {
List<DemoDto> dtos = parentRepo.getDto(3L);
dtos.forEach(System.out::println);
}
}
Result
{parentName=parent2, toyName=Toy7, childName=child3, description=Description1}
{parentName=parent2, toyName=Toy8, childName=child3, description=Description1}
{parentName=parent2, toyName=Toy9, childName=child3, description=Description1}
More info is here.
Working example.

JPA #ElementCollection generates strange unique key

I have an entity class PositionOrdering which contains an element collection:
#ElementCollection(targetClass = Position.class, fetch = FetchType.EAGER)
#CollectionTable(name = "POSITION_ORDERING_POSITION",
joinColumns = #JoinColumn(name = "position_ordering_id"))
#OrderColumn
List<Position> positions = new ArrayList<>();
When hibernate generates the database structure, it looks like this:
CREATE TABLE wls.position_ordering_position
(
position_ordering_id bigint NOT NULL,
positions_id bigint NOT NULL,
positions_order integer NOT NULL,
...
}
It's ok and exactly what I was expected. But it also generate a unique contsraint on positions_id column. It is strange, because the position id should be unique only per ordering, so any of the following unique keys would be ok:
position_ordering_id + positions_order
position_ordering_id + positions_id
But not on the single column of positions_id.
Because the constraint is generated automatically, I can't ignore or remove it simply.
Can I configure my collection to create correct unique constraint or at least not to create any?
UPDATE:
As for request, here is the skeleton of the Position entity:
#Entity
#SequenceGenerator(name = EntityBase.SEQUENCE_NAME,
sequenceName = "POSITION_ID_SEQ")
#Table(name = "position")
public class Position extends EntityBase {
// Lots of fields, like row, column number, and type, etc.
}
Where EntityBase is a simple class with some utility function and with Id:
#MappedSuperclass
public abstract class EntityBase implements Serializable, Cloneable {
public static final String SEQUENCE_NAME = "SEQUENCE_GENERATOR";
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = SEQUENCE_NAME)
protected Long id;
//..
}
#ElementCollection is used for mapping basic types or #Embedded classes, not entities. From the documentation
An ElementCollection can be used to define a one-to-many relationship to an Embeddable object, or a Basic value (such as a collection of Strings).
Since Position is an #Entity, you should map it as #OneToMany or #ManyToMany. I don't know the exact reason why are you getting that unique key generated, but I guess you can expect unpredictable results if you use the annottion in a was that it was not intended for.
As Predrag Maric described it in the accepted answer, the problem was that Position was not an `Embeddable'. My solution was:
I created a support class which wraps the Position into an #Embeddable entity:
#Embeddable
//#Table(name = "position_ordering_position")
public class PositionOrderingPosition {
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "position_id", nullable = false)
private Position position;
public PositionOrderingPosition() {
}
public PositionOrderingPosition(Position position) {
this.position = position;
}
public Position getPosition() {
return position;
}
}
Also I changed the Element collection to this:
#ElementCollection(fetch = FetchType.EAGER)
#CollectionTable(name = "POSITION_ORDERING_POSITION",
joinColumns = #JoinColumn(name = "position_ordering_id"))
#OrderColumn
List<PositionOrderingPosition> positions = new ArrayList<>();
Now it creates the same table, but with the right constraints.

Many-to-many relationship, update referenced Set (update join table) throw NonUniqueObjectException

I am using hibernate. I have a Many-to-Many relationship between Student and Group classes. There is a join table named student_group which has student_id and group_id columns.
Student class:
#Entity
#Table(name = "student")
public class Student {
private int student_id; //primary key
#ManyToMany(mappedBy = "students")
private Set<Group> groups = new HashSet<Group>();
#ManyToMany(cascade = {CascadeType.ALL})
#JoinTable(name="student_group",
joinColumns={#JoinColumn(name="student_id")},
inverseJoinColumns={#JoinColumn(name="group_id")})
public Set<Group> getGroups() {
return groups;
}
public void setGroups(Set<Group> groups) {
this.groups = groups;
}
//Setter & Getter for student_id
...
}
Group class:
#Entity
#Table(name = "group")
public class Group {
private int group_id;//primary key
private Set<Student> students = new HashSet<Student>();
#ManyToMany(cascade = {CascadeType.ALL})
#JoinTable(name="student_group",
joinColumns={#JoinColumn(name="group_id")},
inverseJoinColumns={#JoinColumn(name="student_id")})
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
//Getter & Setting for group_id
...
}
In my main program I have a function which 1st find a student from database, then, add a group to the student and finally try to save the updated student to database:
public void addGroupToStudent(int studentId, Group newGroup){
//open a session & query the database to get a student by id
Session session = sessionFactory.openSession();
Student student = loadStudentById(session, id);
//Get above student's groups
Set<Group> groups = student.getGroups();
//Add the new group
groups.add(newGroup);
//SaveAndUpdate the student in database
Transaction transaction = session.beginTransaction();
try {
session.saveOrUpdate(student);
transaction.commit();
} catch (final HibernateException e) {...}
}
(The newGroup parameter in above function is retrieved from database with another session & query.)
But the above function throw the following exception:
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.my.db.Group#5]
at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:697)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:296)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:241)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:109)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
Where am I wrong? How to get rid of this exception? Generally I just want to update a student's groups in database, which in turns should update the join table.

How to rename a component column that is a foreign key?

We are using fluentnhibernate with automapping and we have a naming convention that all columns that are foreign keys, there column name will end with "Key". So we have a convention that looks like this:
public class ForeignKeyColumnNameConvention : IReferenceConvention
{
public void Apply ( IManyToOneInstance instance )
{
// name the key field
string propertyName = instance.Property.Name;
instance.Column ( propertyName + "Key" );
}
}
This works great until we created a component in which one of its values is a foreign key. By renaming the column here it overrides the default name given to the component column which includes the ComponentPrefix which is defined in the AutomappingConfiguration. Is there a way for me to get the ComponentPrefix in this convention? or is there some other way for me to get the column name for components with a property that is a foreign key to end in the word "Key"?
After a lot of fiddling and trial & error (thus being tempted to use your solution with Reflection) I came up with the following:
This method depends on the order of the execution of the conventions. This convention-order happens via a strict hierarchy. In this example, at first, the convention of the component (IDynamicComponentConvention) is being handled and after that the conventions of the inner properties are being handled such as the References mapping (IReferenceConvention).
The strict order is where we make our strike:
We assemble the correct name of the column in the call to Apply(IDynamicComponentConvention instance), put it on the queue. Note that a Queue<T> is used which is a FIFO (first-in-first-out) collection type thus it keeps the order correctly.
Almost immediately after that, Apply(IManyToOneInstanceinstance) is called. We check if there is anything in the queue. If there is, we take it out of the queue and set it as column name. Note that you should not use Peek() instead of Dequeue() as it does not remove the object from the queue.
The code is as follows:
public sealed class CustomNamingConvention : IDynamicComponentConvention, IReferenceConvention {
private static Queue<string> ColumnNames = new Queue<string>();
public void Apply(IDynamicComponentInstance instance) {
foreach (var referenceInspector in instance.References) {
// All the information we need is right here
// But only to inspect, no editing yet :(
// Don't worry, just assemble the name and enqueue it
var name = string.Format("{0}_{1}",
instance.Name,
referenceInspector.Columns.Single().Name);
ColumnNames.Enqueue(name);
}
}
public void Apply(IManyToOneInstance instance) {
if (!ColumnNames.Any())
// Nothing in the queue? Just return then (^_^)
return;
// Set the retrieved string as the column name
var columnName = ColumnNames.Dequeue();
instance.Column(columnName);
// Pick a beer and celebrate the correct naming!
}
}
I Have figured out a way to do this using reflection to get to the underlying mapping of the IManyToOneInspector exposed by the IComponentInstance but was hoping there was a better way to do this?
Here is some example code of how I achieved this:
#region IConvention<IComponentInspector, IComponentInstance> Members
public void Apply(IComponentInstance instance)
{
foreach (var manyToOneInspector in instance.References)
{
var referenceName = string.Format("{0}_{1}_{2}{3}", instance.EntityType.Name, manyToOneInspector.Property.PropertyType.Name, _autoMappingConfiguration.GetComponentColumnPrefix(instance.Property), manyToOneInspector.Property.Name);
if(manyToOneInspector.Property.PropertyType.IsSubclassOf(typeof(LookupBase)))
{
referenceName += "Lkp";
}
manyToOneInspector.Index ( string.Format ( "{0}_FK_IDX", referenceName ) );
}
}
#endregion
public static class ManyToOneInspectorExtensions
{
public static ManyToOneMapping GetMapping(this IManyToOneInspector manyToOneInspector)
{
var fieldInfo = manyToOneInspector.GetType ().GetField( "mapping", BindingFlags.NonPublic | BindingFlags.Instance );
if (fieldInfo != null)
{
var manyToOneMapping = fieldInfo.GetValue( manyToOneInspector ) as ManyToOneMapping;
return manyToOneMapping;
}
return null;
}
public static void Index(this IManyToOneInspector manyToOneInspector, string indexName)
{
var mapping = manyToOneInspector.GetMapping ();
mapping.Index ( indexName );
}
public static void Column(this IManyToOneInspector manyToOneInspector, string columnName)
{
var mapping = manyToOneInspector.GetMapping ();
mapping.Column ( columnName );
}
public static void ForeignKey(this IManyToOneInspector manyToOneInspector, string foreignKeyName)
{
var mapping = manyToOneInspector.GetMapping();
mapping.ForeignKey ( foreignKeyName );
}
}
public static class ManyToOneMappingExtensions
{
public static void Index (this ManyToOneMapping manyToOneMapping, string indexName)
{
if (manyToOneMapping.Columns.First().IsSpecified("Index"))
return;
foreach (var column in manyToOneMapping.Columns)
{
column.Index = indexName;
}
}
public static void Column(this ManyToOneMapping manyToOneMapping, string columnName)
{
if (manyToOneMapping.Columns.UserDefined.Count() > 0)
return;
var originalColumn = manyToOneMapping.Columns.FirstOrDefault();
var column = originalColumn == null ? new ColumnMapping() : originalColumn.Clone();
column.Name = columnName;
manyToOneMapping.ClearColumns();
manyToOneMapping.AddColumn(column);
}
public static void ForeignKey(this ManyToOneMapping manyToOneMapping, string foreignKeyName)
{
if (!manyToOneMapping.IsSpecified("ForeignKey"))
manyToOneMapping.ForeignKey = foreignKeyName;
}
}