1

私はこのデータモデルを持っています:

AbstractEntity (abstract, @MappedSuperClass)
    |
    +---- Subject (abstract, @Entity, joined)
    |       |
    |       +---- Person (@Entity)
    |       |
    |       +---- ...
    |
    +---- Metadata (abstract, @Entity, joined)
            |
            +---- ...

で実現:

@MappedSuperclass
public abstract class AbstractEntity implements Serializable
{
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(nullable = false)
    protected Long id;

    @Version
    protected Integer version;

    ...
}

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Subject extends AbstractEntity
{
    @ManyToOne
    @JoinColumn(name = "PROFILE_ID")
    protected Profile profile;

    @ElementCollection
    @CollectionTable(name = "SUBJECT_RIGHTS", joinColumns = @JoinColumn(name = "OWNER_ID"))
    @Column(name = "CODE")
    protected Set<String> rightSet = new HashSet<String>();

    @Transient
    public abstract String getTitle();

    ...
}

@Entity
public class Person extends AbstractEntity
{
    @NotBlank
    private String firstName;

    @NotBlank
    private String lastName;

    ...
}

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Metadata extends AbstractEntity
{
    @ElementCollection
    @CollectionTable(name = "METADATA_PREFERENCE", joinColumns = @JoinColumn(name = "METADATA_ID"))
    @MapKeyJoinColumn(name = "PERSON_ID", nullable = false)
    @Enumerated(EnumType.STRING)
    @Column(name = "PREFERENCE", nullable = false)
    protected Map<Person, PreferenceType> preferenceMap = new LinkedHashMap<Person, PreferenceType>();

    ...
}

そして私はこのクエリを実行しようとしています:

select m.id from Metadata m left join m.preferenceMap p [where not important]

eclipselinkは次のSQLを生成します。

SELECT t0.ID FROM METADATA t0 LEFT OUTER JOIN METADATA_PREFERENCE t3 ON ((t3.METADATA_ID = t0.ID) AND (t1.ID = t3.PERSON_ID)), PERSON t2, SUBJECT t1 [where not important]

ただし、このクエリは例外を生成します。

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 't1.ID' in 'on clause'

MySQLの参加の優先順位について知っているので、クエリを次のように書き直すにはeclipselinkが必要です。

SELECT t0.ID FROM (METADATA t0, SUBJECT t1) LEFT OUTER JOIN METADATA_PREFERENCE t3 ON ((t3.METADATA_ID = t0.ID) AND (t1.ID = t3.PERSON_ID)), PERSON t2 [where not important]

これを行う方法???

しかし、私は使用しています:

mysql:
+-------------------------+------------------------------+
| Variable_name           | Value                        |
+-------------------------+------------------------------+
| innodb_version          | 1.1.7                        |
| protocol_version        | 10                           |
| slave_type_conversions  |                              |
| version                 | 5.5.13-log                   |
| version_comment         | MySQL Community Server (GPL) |
| version_compile_machine | x86                          |
| version_compile_os      | Win64                        |
+-------------------------+------------------------------+

eclipselink: 
Eclipse Persistence Services - 2.4.1.v20121003-ad44345

これはpersistence.xmlです

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="prime" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>jdbc/prime</jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="eclipselink.target-database" value="MySQL"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/prime"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="password"/>
        </properties>
    </persistence-unit>
</persistence>
4

2 に答える 2

0

複雑なMapElementCollectionに参加することで混乱しているようです。バグのようです。バグをログに記録して投票してください。また、最新のパッチリリースを使用していることを確認してください。

代わりに、ElementCollectionをOneToManyとして、人とタイプを持つPreferenceオブジェクトにマップすることができます。これは、より単純なモデルになります。

外部結合が必要ない場合は、内部結合も機能する可能性があります(または、外部結合のセマンティクスが必要な場合は、サブクエリを使用します)。

于 2013-01-15T14:38:37.550 に答える
0

eclipselink 2.5.0(jpa 2.1)はこのバグを解決します。

于 2013-12-08T12:50:07.203 に答える